Vernlium/vernlium.github.io

translate_learning

Opened this issue · 1 comments

{
"cells": [
{
"cell_type": "code",
"execution_count": 12,
"metadata": {},
"outputs": [],
"source": [
"import glob\n",
"import os.path\n",
"import random\n",
"import numpy as np\n",
"import tensorflow as tf\n",
"from tensorflow.python.platform import gfile\n",
"import matplotlib.pyplot as plt"
]
},
{
"cell_type": "code",
"execution_count": 13,
"metadata": {},
"outputs": [],
"source": [
"#模型和样本路径的设置\n",
"#inception-V3瓶颈层节点个数\n",
"BOTTLENECK_TENSOR_SIZE = 2048\n",
"#瓶颈层tenbsor name\n",
"BOTTLENECK_TENSOR_NAME = 'pool_3/_reshape:0'\n",
"#图像输入tensor name\n",
"JPEG_DATA_TENSOR_NAME = 'DecodeJpeg/contents:0'\n",
"\n",
"# v3 path\n",
"MODEL_DIR = './inception_dec_2015'\n",
"# v3 modefile\n",
"MODEL_FILE= 'tensorflow_inception_graph.pb'\n",
"\n",
"#特征向量 save path\n",
"CACHE_DIR = './bottleneck'\n",
"#数据path\n",
"INPUT_DATA = './flower_photos'\n",
"\n",
"#验证数据 percentage\n",
"VALIDATION_PERCENTAGE = 10\n",
"#测试数据 percentage\n",
"TEST_PERCENTAGE = 10\n",
"\n",
"#神经网络参数的设置\n",
"LEARNING_RATE = 0.01\n",
"STEPS = 4000\n",
"BATCH = 100"
]
},
{
"cell_type": "code",
"execution_count": 14,
"metadata": {
"scrolled": true
},
"outputs": [],
"source": [
"#把样本中所有的图片列表并按训练、验证、测试数据分开\n",
"def create_image_lists(testing_percentage, validation_percentage):\n",
" result = {}\n",
" sub_dirs = [x[0] for x in os.walk(INPUT_DATA)]\n",
" is_root_dir = True\n",
" for sub_dir in sub_dirs:\n",
" if is_root_dir:\n",
" is_root_dir = False\n",
" continue\n",
"\n",
" extensions = ['jpg', 'jpeg', 'JPG', 'JPEG']\n",
"\n",
" file_list = []\n",
" dir_name = os.path.basename(sub_dir)\n",
" for extension in extensions:\n",
" file_glob = os.path.join(INPUT_DATA, dir_name, '.' + extension)\n",
" file_list.extend(glob.glob(file_glob))\n",
" if not file_list: continue\n",
"\n",
" label_name = dir_name.lower()\n",
"\n",
" # 初始化\n",
" training_images = []\n",
" testing_images = []\n",
" validation_images = []\n",
" for file_name in file_list:\n",
" base_name = os.path.basename(file_name)\n",
"\n",
" # 随机划分数据\n",
" chance = np.random.randint(100)\n",
" if chance < validation_percentage:\n",
" validation_images.append(base_name)\n",
" elif chance < (testing_percentage + validation_percentage):\n",
" testing_images.append(base_name)\n",
" else:\n",
" training_images.append(base_name)\n",
"\n",
" result[label_name] = {\n",
" 'dir': dir_name,\n",
" 'training': training_images,\n",
" 'testing': testing_images,\n",
" 'validation': validation_images,\n",
" }\n",
" return result"
]
},
{
"cell_type": "code",
"execution_count": 15,
"metadata": {},
"outputs": [],
"source": [
"#函数通过类别名称、所属数据集和图片编号获取一张图片的地址\n",
"def get_image_path(image_lists, image_dir, label_name, index, category):\n",
" label_lists = image_lists[label_name]\n",
" category_list = label_lists[category]\n",
" mod_index = index % len(category_list)\n",
" base_name = category_list[mod_index]\n",
" sub_dir = label_lists['dir']\n",
" full_path = os.path.join(image_dir, sub_dir, base_name)\n",
" return full_path\n"
]
},
{
"cell_type": "code",
"execution_count": 16,
"metadata": {},
"outputs": [],
"source": [
"#函数获取Inception-v3模型处理之后的特征向量的文件地址\n",
"def get_bottleneck_path(image_lists, label_name, index, category):\n",
" return get_image_path(image_lists, CACHE_DIR, label_name, index, category) + '.txt'\n"
]
},
{
"cell_type": "code",
"execution_count": 17,
"metadata": {},
"outputs": [],
"source": [
"#函数使用加载的训练好的Inception-v3模型处理一张图片,得到这个图片的特征向量。\n",
"def run_bottleneck_on_image(sess, image_data, image_data_tensor, bottleneck_tensor):\n",
"\n",
" bottleneck_values = sess.run(bottleneck_tensor, {image_data_tensor: image_data})\n",
"\n",
" bottleneck_values = np.squeeze(bottleneck_values)\n",
" return bottleneck_values\n"
]
},
{
"cell_type": "code",
"execution_count": 18,
"metadata": {},
"outputs": [],
"source": [
"#函数会先试图寻找已经计算且保存下来的特征向量,如果找不到则先计算这个特征向量,然后保存到文件\n",
"def get_or_create_bottleneck(sess, image_lists, label_name, index, category, jpeg_data_tensor, bottleneck_tensor):\n",
" label_lists = image_lists[label_name]\n",
" sub_dir = label_lists['dir']\n",
" sub_dir_path = os.path.join(CACHE_DIR, sub_dir)\n",
" if not os.path.exists(sub_dir_path): os.makedirs(sub_dir_path)\n",
" bottleneck_path = get_bottleneck_path(image_lists, label_name, index, category)\n",
" if not os.path.exists(bottleneck_path):\n",
"\n",
" image_path = get_image_path(image_lists, INPUT_DATA, label_name, index, category)\n",
"\n",
" image_data = gfile.FastGFile(image_path, 'rb').read()\n",
"\n",
" bottleneck_values = run_bottleneck_on_image(sess, image_data, jpeg_data_tensor, bottleneck_tensor)\n",
"\n",
" bottleneck_string = ','.join(str(x) for x in bottleneck_values)\n",
" with open(bottleneck_path, 'w') as bottleneck_file:\n",
" bottleneck_file.write(bottleneck_string)\n",
" else:\n",
"\n",
" with open(bottleneck_path, 'r') as bottleneck_file:\n",
" bottleneck_string = bottleneck_file.read()\n",
" bottleneck_values = [float(x) for x in bottleneck_string.split(',')]\n",
"\n",
" return bottleneck_values"
]
},
{
"cell_type": "code",
"execution_count": 19,
"metadata": {},
"outputs": [],
"source": [
"#函数随机获取一个batch的图片作为训练数据\n",
"def get_random_cached_bottlenecks(sess, n_classes, image_lists, how_many, category, jpeg_data_tensor, bottleneck_tensor):\n",
" bottlenecks = []\n",
" ground_truths = []\n",
" for _ in range(how_many):\n",
" label_index = random.randrange(n_classes)\n",
" label_name = list(image_lists.keys())[label_index]\n",
" image_index = random.randrange(65536)\n",
" bottleneck = get_or_create_bottleneck(\n",
" sess, image_lists, label_name, image_index, category, jpeg_data_tensor, bottleneck_tensor)\n",
" ground_truth = np.zeros(n_classes, dtype=np.float32)\n",
" ground_truth[label_index] = 1.0\n",
" bottlenecks.append(bottleneck)\n",
" ground_truths.append(ground_truth)\n",
"\n",
" return bottlenecks, ground_truths\n"
]
},
{
"cell_type": "code",
"execution_count": 20,
"metadata": {},
"outputs": [],
"source": [
"#获取全部的测试数据,并计算正确率\n",
"def get_test_bottlenecks(sess, image_lists, n_classes, jpeg_data_tensor, bottleneck_tensor):\n",
" bottlenecks = []\n",
" ground_truths = []\n",
" label_name_list = list(image_lists.keys())\n",
" for label_index, label_name in enumerate(label_name_list):\n",
" category = 'testing'\n",
" for index, unused_base_name in enumerate(image_lists[label_name][category]):\n",
" bottleneck = get_or_create_bottleneck(sess, image_lists, label_name, index, category,jpeg_data_tensor, bottleneck_tensor)\n",
" ground_truth = np.zeros(n_classes, dtype=np.float32)\n",
" ground_truth[label_index] = 1.0\n",
" bottlenecks.append(bottleneck)\n",
" ground_truths.append(ground_truth)\n",
" return bottlenecks, ground_truths"
]
},
{
"cell_type": "code",
"execution_count": 29,
"metadata": {},
"outputs": [],
"source": [
"\n",
"def train():\n",
" image_lists = create_image_lists(TEST_PERCENTAGE, VALIDATION_PERCENTAGE)\n",
" n_classes = len(image_lists.keys())\n",
"\n",
" # 读取已经训练好的Inception-v3模型。\n",
" with gfile.FastGFile(os.path.join(MODEL_DIR, MODEL_FILE), 'rb') as f:\n",
" graph_def = tf.GraphDef()\n",
" graph_def.ParseFromString(f.read())\n",
" bottleneck_tensor, jpeg_data_tensor = tf.import_graph_def(\n",
" graph_def, return_elements=[BOTTLENECK_TENSOR_NAME, JPEG_DATA_TENSOR_NAME])\n",
"\n",
" # 定义新的神经网络输入\n",
" bottleneck_input = tf.placeholder(tf.float32, [None, BOTTLENECK_TENSOR_SIZE], name='BottleneckInputPlaceholder')\n",
" ground_truth_input = tf.placeholder(tf.float32, [None, n_classes], name='GroundTruthInput')\n",
"\n",
" # 定义一层全链接层\n",
" with tf.name_scope('final_training_ops'):\n",
" weights = tf.Variable(tf.truncated_normal([BOTTLENECK_TENSOR_SIZE, n_classes], stddev=0.001))\n",
" biases = tf.Variable(tf.zeros([n_classes]))\n",
" logits = tf.matmul(bottleneck_input, weights) + biases\n",
" final_tensor = tf.nn.softmax(logits)\n",
"\n",
" # 定义交叉熵损失函数。\n",
" cross_entropy = tf.nn.softmax_cross_entropy_with_logits(logits=logits, labels=ground_truth_input)\n",
" cross_entropy_mean = tf.reduce_mean(cross_entropy)\n",
" train_step = tf.train.GradientDescentOptimizer(LEARNING_RATE).minimize(cross_entropy_mean)\n",
"\n",
" # 计算正确率。\n",
" with tf.name_scope('evaluation'):\n",
" correct_prediction = tf.equal(tf.argmax(final_tensor, 1), tf.argmax(ground_truth_input, 1))\n",
" evaluation_step = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))\n",
"\n",
" costs = [] \n",
" \n",
" with tf.Session() as sess:\n",
"# merged = tf.summary.merge_all()\n",
"# train_writer = tf.summary.FileWriter("./../../tensorboard_logs",sess.graph)\n",
"# test_writer = tf.summary.FileWriter("./../../tensorboard_logs")\n",
" \n",
" init = tf.global_variables_initializer()\n",
" sess.run(init)\n",
" # 训练过程。\n",
" for i in range(STEPS):\n",
"\n",
" train_bottlenecks, train_ground_truth = get_random_cached_bottlenecks(\n",
" sess, n_classes, image_lists, BATCH, 'training', jpeg_data_tensor, bottleneck_tensor)\n",
"# summary, _ = sess.run([merged,train_step], feed_dict={bottleneck_input: train_bottlenecks, ground_truth_input: train_ground_truth})\n",
" \n",
" _,temp_cost = sess.run([train_step,cross_entropy_mean], feed_dict={bottleneck_input: train_bottlenecks, ground_truth_input: train_ground_truth})\n",
" \n",
" costs.append(temp_cost)\n",
" # train_writer.add_summary(summary, i)\n",
" \n",
" if i % 100 == 0 or i + 1 == STEPS:\n",
" validation_bottlenecks, validation_ground_truth = get_random_cached_bottlenecks(\n",
" sess, n_classes, image_lists, BATCH, 'validation', jpeg_data_tensor, bottleneck_tensor)\n",
"# summary, validation_accuracy = sess.run([merged, evaluation_step], feed_dict={\n",
"# bottleneck_input: validation_bottlenecks, ground_truth_input: validation_ground_truth})\n",
" validation_accuracy = sess.run(evaluation_step, feed_dict={\n",
" bottleneck_input: validation_bottlenecks, ground_truth_input: validation_ground_truth})\n",
" print('Step %d: Validation accuracy on random sampled %d examples = %.1f%%' %\n",
" (i, BATCH, validation_accuracy * 100))\n",
"# test_writer.add_summary(summary, i)\n",
"\n",
" # plot the cost\n",
" plt.plot(np.squeeze(costs))\n",
" plt.ylabel('cost')\n",
" plt.xlabel('iterations (per tens)')\n",
" plt.title("Learning rate =" + str(LEARNING_RATE))\n",
" plt.show()\n",
" \n",
" # 在最后的测试数据上测试正确率。\n",
" test_bottlenecks, test_ground_truth = get_test_bottlenecks(\n",
" sess, image_lists, n_classes, jpeg_data_tensor, bottleneck_tensor)\n",
" sess.run(evaluation_step, feed_dict={\n",
" bottleneck_input: test_bottlenecks, ground_truth_input: test_ground_truth})\n",
" print('Final test accuracy = %.1f%%' % (test_accuracy * 100))"
]
},
{
"cell_type": "code",
"execution_count": 30,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Step 0: Validation accuracy on random sampled 100 examples = 37.0%\n",
"Step 100: Validation accuracy on random sampled 100 examples = 84.0%\n",
"Step 200: Validation accuracy on random sampled 100 examples = 84.0%\n",
"Step 300: Validation accuracy on random sampled 100 examples = 88.0%\n",
"Step 400: Validation accuracy on random sampled 100 examples = 87.0%\n",
"Step 500: Validation accuracy on random sampled 100 examples = 91.0%\n",
"Step 600: Validation accuracy on random sampled 100 examples = 91.0%\n",
"Step 700: Validation accuracy on random sampled 100 examples = 91.0%\n",
"Step 800: Validation accuracy on random sampled 100 examples = 93.0%\n",
"Step 900: Validation accuracy on random sampled 100 examples = 94.0%\n",
"Step 1000: Validation accuracy on random sampled 100 examples = 89.0%\n",
"Step 1100: Validation accuracy on random sampled 100 examples = 91.0%\n",
"Step 1200: Validation accuracy on random sampled 100 examples = 90.0%\n",
"Step 1300: Validation accuracy on random sampled 100 examples = 92.0%\n",
"Step 1400: Validation accuracy on random sampled 100 examples = 88.0%\n",
"Step 1500: Validation accuracy on random sampled 100 examples = 91.0%\n",
"Step 1600: Validation accuracy on random sampled 100 examples = 90.0%\n",
"Step 1700: Validation accuracy on random sampled 100 examples = 90.0%\n",
"Step 1800: Validation accuracy on random sampled 100 examples = 86.0%\n",
"Step 1900: Validation accuracy on random sampled 100 examples = 94.0%\n",
"Step 2000: Validation accuracy on random sampled 100 examples = 97.0%\n",
"Step 2100: Validation accuracy on random sampled 100 examples = 96.0%\n",
"Step 2200: Validation accuracy on random sampled 100 examples = 95.0%\n",
"Step 2300: Validation accuracy on random sampled 100 examples = 99.0%\n",
"Step 2400: Validation accuracy on random sampled 100 examples = 96.0%\n",
"Step 2500: Validation accuracy on random sampled 100 examples = 95.0%\n",
"Step 2600: Validation accuracy on random sampled 100 examples = 94.0%\n",
"Step 2700: Validation accuracy on random sampled 100 examples = 95.0%\n",
"Step 2800: Validation accuracy on random sampled 100 examples = 97.0%\n",
"Step 2900: Validation accuracy on random sampled 100 examples = 98.0%\n",
"Step 3000: Validation accuracy on random sampled 100 examples = 94.0%\n",
"Step 3100: Validation accuracy on random sampled 100 examples = 92.0%\n",
"Step 3200: Validation accuracy on random sampled 100 examples = 95.0%\n",
"Step 3300: Validation accuracy on random sampled 100 examples = 91.0%\n",
"Step 3400: Validation accuracy on random sampled 100 examples = 94.0%\n",
"Step 3500: Validation accuracy on random sampled 100 examples = 95.0%\n",
"Step 3600: Validation accuracy on random sampled 100 examples = 97.0%\n",
"Step 3700: Validation accuracy on random sampled 100 examples = 91.0%\n",
"Step 3800: Validation accuracy on random sampled 100 examples = 95.0%\n",
"Step 3900: Validation accuracy on random sampled 100 examples = 96.0%\n",
"Step 3999: Validation accuracy on random sampled 100 examples = 95.0%\n"
]
},
{
"data": {
"image/png": "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\n",
"text/plain": [
"<Figure size 432x288 with 1 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"ename": "NameError",
"evalue": "name 'test_accuracy' is not defined",
"output_type": "error",
"traceback": [
"\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
"\u001b[1;31mNameError\u001b[0m Traceback (most recent call last)",
"\u001b[1;32m\u001b[0m in \u001b[0;36m\u001b[1;34m()\u001b[0m\n\u001b[1;32m----> 1\u001b[1;33m \u001b[0mtrain\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m",
"\u001b[1;32m\u001b[0m in \u001b[0;36mtrain\u001b[1;34m()\u001b[0m\n\u001b[0;32m 76\u001b[0m sess.run(evaluation_step, feed_dict={\n\u001b[0;32m 77\u001b[0m bottleneck_input: test_bottlenecks, ground_truth_input: test_ground_truth})\n\u001b[1;32m---> 78\u001b[1;33m \u001b[0mprint\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;34m'Final test accuracy = %.1f%%'\u001b[0m \u001b[1;33m%\u001b[0m \u001b[1;33m(\u001b[0m\u001b[0mtest_accuracy\u001b[0m \u001b[1;33m
\u001b[0m \u001b[1;36m100\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m",
"\u001b[1;31mNameError\u001b[0m: name 'test_accuracy' is not defined"
]
}
],
"source": [
"train()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# 读取已经训练好的Inception-v3模型。\n",
"with gfile.FastGFile(os.path.join(MODEL_DIR, MODEL_FILE), 'rb') as f:\n",
" graph_def = tf.GraphDef()\n",
" graph_def.ParseFromString(f.read())\n",
"\n",
"bottleneck_tensor, jpeg_data_tensor = tf.import_graph_def(\n",
" graph_def, return_elements=[BOTTLENECK_TENSOR_NAME, JPEG_DATA_TENSOR_NAME])"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"print(bottleneck_tensor)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"image_lists = create_image_lists(TEST_PERCENTAGE, VALIDATION_PERCENTAGE)\n",
"n_classes = len(image_lists.keys())\n",
"print(n_classes)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"print("dir_name=" + image_lists["roses"]["dir"])\n",
"\n",
"print("training num =" + str(len(image_lists["roses"]["validation"])))\n",
"\n",
"print("testing num =" + str(len(image_lists["roses"]["testing"])))\n",
"print("validation num =" + str(len(image_lists["roses"]["validation"])))\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"print(image_lists.keys())"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"import matplotlib.pyplot as plt"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"import numpy as np"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
}
},
"nbformat": 4,
"nbformat_minor": 2
}