TensorFlow 實戰Google深度學習框架(第2版)第6章之LeNet-5模型實現MNIST數字識別
本篇為記錄樓主在學習《TensorFlow 實戰Google深度學習框架(第2版)》第6章 利用LeNet-5模型實現MNIST數字識別過程中遇到的一些問題的記錄、彙總。
mnist_train_cnn.py程式的輸入資料格式應做調整。主要有兩處:
- 這裡,在使用tf.placeholder時要指明張量第一維的長度,即shape裡第一位不能像之前一樣為None,否則會報錯“Failed to convert object of type <class ‘list’> to Tensor. Contents: [None, 3136]. Consider casting ”。
x = tf.placeholder(tf.float32,
[BATCH_SIZE,
mnist_inference_cnn.IMAGE_SIZE,
mnist_inference_cnn.IMAGE_SIZE,
mnist_inference_cnn.NUM_CHANNELS],
name = "x-input")
y_ = tf.placeholder(tf.float32,
[BATCH_SIZE,
mnist_inference_cnn.NUM_LABELS],name = "y-input")
- 這裡,不能使用tf.reshape來調整資料格式,而應該使用np.reshape,即numpy裡面的reshape命令,否則會報錯“typeError:The value of a feed cannot be a tf.Tensor object.Acceptable feed values include Python scalars,strings,lists.numpy ndarrays,or TensorHandles.For reference.the tensor object was Tensor…”。這裡的錯誤資訊解釋得很清楚。所以,我們需要用np.reshape,這樣結果就不是一個tensor。
reshaped_xs = np.reshape(xs,
[BATCH_SIZE,
mnist_inference_cnn.IMAGE_SIZE,
mnist_inference_cnn.IMAGE_SIZE,
mnist_inference_cnn.NUM_CHANNELS])
下面給出了完整的訓練程式碼:
# _*_ coding:utf-8 _*_
import tensorflow as tf
IMAGE_SIZE = 28
NUM_CHANNELS = 1
NUM_LABELS = 10
# 第一層卷積層的尺寸和深度
CONV1_SIZE = 5
CONV1_DEEP = 32
# 第二層卷積層的尺寸和深度
CONV2_SIZE = 5
CONV2_DEEP = 64
# 全連線層的節點個數
FC_SIZE = 512
def inference(input_tensor,train, regularizer):
# 第一層:卷積層。過濾器或核心的尺寸為5*5,深度為32,步長為1,使用全0填充
# 輸入:BATCH_SIZE*28*28*1的張量
# 輸出:BATCH_SIZE*28*28*32的張量
with tf.variable_scope("layer1-conv1"):
conv1_weight = tf.get_variable("weight",[CONV1_SIZE, CONV1_SIZE, NUM_CHANNELS, CONV1_DEEP],
initializer = tf.truncated_normal_initializer(stddev=0.1))
conv1_bias = tf.get_variable("bias",[CONV1_DEEP], initializer = tf.constant_initializer(0.0))
conv1 = tf.nn.conv2d(input_tensor, conv1_weight, strides = [1,1,1,1], padding="SAME")
relu1 = tf.nn.relu(tf.nn.bias_add(conv1, conv1_bias))
# 第二層:池化層。過濾器的尺寸為2*2,步長為2
# 輸入:BATCH_SIZE*28828*32的張量
# 輸出:BATCH_SIZE*14*14*32的張量
with tf.variable_scope("layer2-pool1"):
pool1 = tf.nn.max_pool(relu1, ksize=[1,2,2,1], strides = [1,2,2,1],padding="SAME")
# 第三層:卷積層。過濾器或核心的尺寸為5*5,深度為64,步長為1,使用全0填充
# 輸入:BATCH_SIZE*14*14*32的張量
# 輸出:BATCH_SIZE*14*14*64的張量
with tf.variable_scope("layer3-conv2"):
conv2_weight = tf.get_variable("weight", [CONV2_SIZE, CONV2_SIZE, CONV1_DEEP, CONV2_DEEP],
initializer = tf.truncated_normal_initializer(stddev=0.1))
conv2_bias = tf.get_variable("bias", [CONV2_DEEP], initializer = tf.constant_initializer(0.0))
conv2 = tf.nn.conv2d(pool1, conv2_weight, strides = [1,1,1,1], padding="SAME")
relu2 = tf.nn.relu(tf.nn.bias_add(conv2, conv2_bias))
# 第四層:池化層。過濾器的尺寸為2,步長為2
# 輸入:BATCH_SIZE*14*14*64的張量
# 輸出:BATCH_SIZE*7*7*64的張量
with tf.variable_scope("layer4-pool2"):
pool2 = tf.nn.max_pool(relu2, ksize = [1,2,2,1], strides = [1,2,2,1], padding="SAME")
# 將BATCH_SIZE*7*7*64的四維張量重新組織為BATCH_SIZE*3136的二維張量
pool_shape = pool2.get_shape().as_list()
nodes = pool_shape[1]*pool_shape[2]*pool_shape[3]
reshaped = tf.reshape(pool2,[pool_shape[0],nodes])
# 第五層:全連線層
# 輸入:BATCH_SIZE*3136的張量
# 輸出:BATCH_SIZE*512的張量
with tf.variable_scope("layer5-cf1"):
fc1_weight = tf.get_variable("weight", [nodes, FC_SIZE],
initializer = tf.truncated_normal_initializer(stddev=0.1))
fc1_bias = tf.get_variable("bias",[FC_SIZE], initializer = tf.constant_initializer(0.1))
fc1 = tf.nn.relu(tf.matmul(reshaped, fc1_weight)+fc1_bias)
if regularizer != None:
tf.add_to_collection("losses", regularizer(fc1_weight))
if train:
fc1 = tf.nn.dropout(fc1,0.5)
# 第六層:全連線層
# 輸入:BATCH_SIZE*512的張量
# 輸出:BATCH_SIZE*10的張量
with tf.variable_scope("layer6-cf2"):
fc2_weight = tf.get_variable("weight", [FC_SIZE, NUM_LABELS],
initializer = tf.truncated_normal_initializer(stddev=0.1))
fc2_bias = tf.get_variable("bias", [NUM_LABELS], initializer = tf.constant_initializer(0.1))
fc2 = tf.matmul(fc1, fc2_weight) + fc2_bias
if regularizer != None:
tf.add_to_collection("losses", regularizer(fc2_weight))
return fc2
# _*_ coding: utf-8 _*_
import os
import tensorflow as tf
import numpy as np
from tensorflow.examples.tutorials.mnist import input_data
import mnist_inference_cnn
BATCH_SIZE = 100
LEARNING_RATE_BASE = 0.8
LEARNING_RATE_DECAY = 0.99
REGULARIZATION_RATE = 0.001
MOVING_AVERAGE_DECAY = 0.99
TRAINING_STEPS = 30000
# 模型儲存的路徑和檔名
MODEL_SAVE_PATH = "/path" # 替換成自己的路徑
MODEL_NAME = "model.ckpt"
def train(mnist):
x = tf.placeholder(tf.float32,
[BATCH_SIZE,
mnist_inference_cnn.IMAGE_SIZE,
mnist_inference_cnn.IMAGE_SIZE,
mnist_inference_cnn.NUM_CHANNELS],
name = "x-input")
y_ = tf.placeholder(tf.float32,
[BATCH_SIZE,
mnist_inference_cnn.NUM_LABELS],name = "y-input")
regularizer = tf.contrib.layers.l2_regularizer(REGULARIZATION_RATE)
# 前向傳播,使用dropout
y = mnist_inference_cnn.inference(x, 1, regularizer)
global_step = tf.Variable(0, trainable=False)
# 計算cross-entropy和loss
cross_entropy = tf.nn.sparse_softmax_cross_entropy_with_logits(logits = y, labels = tf.argmax(y_,1))
cross_entropy_mean = tf.reduce_mean(cross_entropy)
loss = cross_entropy_mean + tf.add_n(tf.get_collection("losses"))
# 設定滑動平均
variables_average_op = tf.train.ExponentialMovingAverage(MOVING_AVERAGE_DECAY,global_step).apply(tf.trainable_variables())
# 反向傳播
learning_rate = tf.train.exponential_decay(LEARNING_RATE_BASE,
global_step,
mnist.train.num_examples / BATCH_SIZE,
LEARNING_RATE_DECAY,
staircase = True)
train_step = tf.train.GradientDescentOptimizer(learning_rate).minimize(loss, global_step=global_step)
train_op = tf.group(train_step, variables_average_op)
saver = tf.train.Saver()
with tf.Session() as sess:
init_op = tf.global_variables_initializer()
sess.run(init_op)
for i in range(TRAINING_STEPS):
xs, ys = mnist.train.next_batch(BATCH_SIZE)
reshaped_xs = np.reshape(xs,
[BATCH_SIZE,
mnist_inference_cnn.IMAGE_SIZE,
mnist_inference_cnn.IMAGE_SIZE,
mnist_inference_cnn.NUM_CHANNELS])
_, loss_value, step = sess.run([train_op, loss, global_step], feed_dict={x:reshaped_xs, y_:ys})
# 每1000輪儲存一次模型
if i % 1000 == 0:
# 輸出當前的訓練情況
print("%d 輪訓練後,訓練batch上的損失為%g" % (step, loss_value))
# 儲存當前的模型
saver.save(sess, os.path.join(MODEL_SAVE_PATH, MODEL_NAME), global_step = global_step)
def main(argv=None):
mnist = input_data.read_data_sets("/path", one_hot = True) # 替換成自己的路徑
train(mnist)
if __name__ == "__main__":
tf.app.run()
相關文章
- mnist手寫數字識別——深度學習入門專案(tensorflow+keras+Sequential模型)深度學習Keras模型
- 推薦閱讀《Tensorflow:實戰Google深度學習框架》Go深度學習框架
- 《Tensorflow:實戰Google深度學習框架》圖書推薦Go深度學習框架
- 用tensorflow2實現mnist手寫數字識別
- 【TensorFlow篇】--Tensorflow框架實現SoftMax模型識別手寫數字集框架模型
- Python深度學習入門之mnist-inception(Tensorflow2.0實現)Python深度學習
- 深度學習實驗:Softmax實現手寫數字識別深度學習
- 深度學習例項之基於mnist的手寫數字識別深度學習
- 深度學習之tensorflow2實戰:多輸出模型深度學習模型
- Pytorch搭建MyNet實現MNIST手寫數字識別PyTorch
- TensorFlow.NET機器學習入門【5】採用神經網路實現手寫數字識別(MNIST)機器學習神經網路
- Tensorflow2.0-mnist手寫數字識別示例
- 深度學習之Tensorflow框架深度學習框架
- 在PaddlePaddle上實現MNIST手寫體數字識別
- Tensorflow實現RNN(LSTM)手寫數字識別RNN
- 深度學習:TensorFlow入門實戰深度學習
- 機器學習實戰-SVM模型實現人臉識別機器學習模型
- 深度學習-行人重識別實戰(2020)深度學習
- 基於TensorFlow的深度學習實戰深度學習
- 實戰 | 基於深度學習模型VGG的影象識別(附程式碼)深度學習模型
- 【Tensorflow_DL_Note12】TensorFlow中LeNet-5模型的實現程式碼模型
- 實戰四:手把手教你實現數字識別
- TensorFlow系列專題(六):實戰專案Mnist手寫資料集識別
- 深度學習Tensorflow實戰,新課進行曲!深度學習
- 【深度學習-基於Tensorflow的實戰】公開課實況深度學習
- 【Get】用深度學習識別手寫數字深度學習
- 學習Pytorch+Python之MNIST手寫字型識別PyTorchPython
- 深度學習之PyTorch實戰(4)——遷移學習深度學習PyTorch遷移學習
- 《深度學習之TensorFlow》pdf深度學習
- Google開源TensorFlow強化學習框架!Go強化學習框架
- 當Spark遇上TensorFlow分散式深度學習框架原理和實踐Spark分散式深度學習框架
- TensorFlow筆記(5)——優化手寫數字識別模型之優化器筆記優化模型
- Pytorch 手寫數字識別 深度學習基礎分享PyTorch深度學習
- 手把手教你運用深度學習構建影片人臉識別模型(Python實現)深度學習模型Python
- 【小白學PyTorch】8 實戰之MNIST小試牛刀PyTorch
- [OpenCV實戰]1 基於深度學習識別人臉性別和年齡OpenCV深度學習
- TensorFlow-1: 如何識別數字
- 利用OpenCV和深度學習來實現人類活動識別OpenCV深度學習