一直都很困扰,tf官方文档直接就读取mnist的数据集了,如果是自己的图片怎么办呢?
找到了denny的代码。
为了验证是否准确率达标,用Lenet模型读取Mnist的图片形式的数据,看一看识别率。下面是根据denny改的代码。
大概原理是:将图片读为array,然后通过yield和feed送入sess.run()里。
有问题的代码:内存不足
# -*- coding: utf-8 -*-
from skimage import io, transform
import glob
import os
import tensorflow as tf
import numpy as np
# 图片数据准备
TRAIN_VALIDATION_DIR = r'F:\CodingTests\python\TensorFlow\TrafficJamImagesDataSets\TrafficJamImages\Train\\'
VALIDATION_PERSENTAGE = 0.1
# 将图片resize为486*486*3
RESIZE_WIDTH = 200
RESIZE_HEIGHT = 200
RESIZE_CHANNEL = 3
# 网络结构
INPUT_NODE = RESIZE_WIDTH * RESIZE_HEIGHT
OUTPUT_NODE = 2
LEARNING_RATE = 0.001
# 训练过程
MAX_TRAIN_ITER = 1000
BATCH_SIZE = 10
def ReadImage2Array(train_validation_dir):
"""
ReadImage2Array()
读取图片为矩阵
"""
train_validation_class_dir = [train_validation_dir + classname # 加上Train文件夹内的各类名作为路径
for classname in os.listdir(train_validation_dir) if os.path.isdir(train_validation_dir + classname)]
images = []
labels = []
for idx, folder in enumerate(train_validation_class_dir):
for oneImagePath in glob.glob(folder + '/*.jpg'):
print('reading the image:%s' % oneImagePath)
oneImage = io.imread(oneImagePath)
oneImage = transform.resize(oneImage, (RESIZE_WIDTH, RESIZE_HEIGHT))
images.append(oneImage)
labels.append(idx)
return np.asarray(images, np.float32), np.asarray(labels, np.int32)
def Shuffle_Devide_Images(images, labels):
"""
打乱图片数据 + 划分训练、验证数据集
:param images:
:param labels:
:return:
"""
# 打乱图片顺序
allImagesQuantity = images.shape[0] # 为[图片数量,图片宽,图片高,图片通道数]的4位矩阵,所以shape[0]是图片数量
allImagesQuantityList = np.arange(allImagesQuantity)
np.random.shuffle(allImagesQuantityList)
shuffledImages = images[allImagesQuantityList]
shuffledLabels = labels[allImagesQuantityList]
# 划分为train和validation两部分
trainImageQuantity = np.int(allImagesQuantity * VALIDATION_PERSENTAGE)
imageTrain = shuffledImages[:trainImageQuantity]
labelTrain = shuffledLabels[:trainImageQuantity]
imageValidation = shuffledImages[trainImageQuantity:]
labelValidation = shuffledLabels[trainImageQuantity:]
return imageTrain, labelTrain, imageValidation, labelValidation
def GetMiniBatches(images, labels, batch_size, shuffle = False):
"""
批量取数据(images, labels)
:param images:
:param labels:
:param batch_size:
:param shuffle:
:return:
"""
assert len(images) == len(labels)
if shuffle:
shuffledIdxs = np.arange(len(images))
np.random.shuffle(shuffledIdxs)
for startIdx in range(0, len(images) - 1, batch_size):
if shuffle:
shuffledBatchedIdxs = shuffledIdxs[startIdx : startIdx + batch_size]
else:
shuffledBatchedIdxs = slice(startIdx, startIdx + batch_size)
oneBatchImages = images[shuffledBatchedIdxs]
oneBatchLabels = labels[shuffledBatchedIdxs]
yield oneBatchImages, oneBatchLabels
def InferenceForward(x, trainOrTest):
"""
前向传播的推导过程,输入image,输出识别结果
:param x:
:return:
"""
CONV1_DEEP = 32
CONV1_SIZE = 5
CONV2_DEEP = 64
CONV2_SIZE = 5
FC_SIZE = 512
with tf.variable_scope('layer1-conv1'):
conv1_weights = tf.get_variable("weight", [CONV1_SIZE, CONV1_SIZE, RESIZE_CHANNEL, CONV1_DEEP], initializer = tf.truncated_normal_initializer(stddev = 0.1))
conv1_biases = tf.get_variable("bias" , [CONV1_DEEP], initializer = tf.constant_initializer(0.0))
conv1 = tf.nn.conv2d(x, conv1_weights, strides = [1, 1, 1, 1], padding = 'SAME')
relu1 = tf.nn.relu(tf.nn.bias_add(conv1, conv1_biases))
with tf.name_scope('layer2-pool1'):
pool1 = tf.nn.max_pool(relu1, ksize = [1, 2, 2, 1], strides = [1, 2, 2, 1], padding = 'SAME')
with tf.variable_scope('layer3-conv2'):
conv2_weights = tf.get_variable("weight", [CONV2_SIZE, CONV2_SIZE, CONV1_DEEP, CONV2_DEEP], initializer = tf.truncated_normal_initializer(stddev = 0.1))
conv2_biases = tf.get_variable("bias", [CONV2_DEEP], initializer = tf.constant_initializer(0.0))
conv2 = tf.nn.conv2d(relu1, conv2_weights, strides = [1, 1, 1, 1], padding = 'SAME')
relu2 = tf.nn.relu(tf.nn.bias_add(conv2, conv2_biases))
with tf.name_scope('layer4-pool2'):
pool2 = tf.nn.max_pool(relu2, ksize = [1, 2, 2, 1], strides = [1, 2, 2, 1], padding = 'SAME')
# 全连接层4维矩阵变为2维矩阵(宽、高、通道三维 变为 一维)
pool2_shape = pool2.get_shape().as_list()
pool2_newShapeSize = pool2_shape[1] * pool2_shape[2] * pool2_shape[3]
pool2_reshaped = tf.reshape(pool2, [-1, pool2_newShapeSize])
with tf.variable_scope('layer5-fc1'):
fc1_weights = tf.get_variable("weights", [pool2_reshaped, FC_SIZE], initializer = tf.truncated_normal_initializer(stddev = 0.1))
fc1_biases = tf.get_variable("bias", [FC_SIZE], initializer = tf.constant_initializer(0.0))
fc1 = tf.nn.relu(tf.matmul(pool2_reshaped, fc1_weights) + fc1_biases)
if trainOrTest == 'train':
fc1 = tf.nn.dropout(fc1, 0.5)
with tf.variable_scope('layer6-fc2'):
fc2_weights = tf.get_variable("weights", [fc1, OUTPUT_NODE], initializer = tf.truncated_normal_initializer(stddev = 0.1))
fc2_biases = tf.get_variable("bias", [OUTPUT_NODE], initializer = tf.constant_initializer(0.0))
logit = tf.matmul(fc1, fc2_weights) + fc2_biases
return logit
def train():
# 读图
images, labels = ReadImage2Array (TRAIN_VALIDATION_DIR)
imageTrain, labelTrain, imageValidation, labelValidation = Shuffle_Devide_Images(images, labels)
# 前向传播
x = tf.placeholder(tf.float32, shape = [None, RESIZE_WIDTH, RESIZE_HEIGHT, RESIZE_CHANNEL], name = 'x')
y_ = tf.placeholder(tf.int32, shape = [None, ], name = 'y_')
y = InferenceForward(x, 'train')
# 训练的过程
loss = tf.losses.sparse_softmax_cross_entropy(labels = y_, logits = y)
train_op = tf.train.AdamOptimizer(learning_rate = LEARNING_RATE).minimize(loss)
# 识别结果
class_OutputResult = tf.argmax(y, 1) # 输出向量y,找出其最大元素对应的下标,就是输出的类别
bools_IsOutputPredictionsRight = tf.equal(tf.cast(class_OutputResult), tf.float32) # 识别结果是否正确的bool值
accuracyRate = tf.reduce_mean(tf.cast(bools_IsOutputPredictionsRight, tf.float32)) # 若干张图,识别正确的数量 / 总图片数量
sess = tf.InteractiveSession()
sess.run(tf.global_variables_initializer())
for epoch in range(MAX_TRAIN_ITER):
# train
allImagesTrainLoss, allImagesTrainAcc, n_TrainBatch = 0, 0, 0
for images_OneBatchTrain, labels_oneBatchTrain in GetMiniBatches(imageTrain, labelTrain, BATCH_SIZE, shuffle = False):
_, oneBatchTrainLoss, oneBatchTrainAcc = sess.run([train_op, loss, accuracyRate], feed_dict = {x:images_OneBatchTrain, y: labels_oneBatchTrain})
allImagesTrainLoss += oneBatchTrainLoss
allImagesTrainAcc += oneBatchTrainAcc
n_TrainBatch += 1
if (epoch % 100 == 0):
# validation
allImagesValidationAcc, n_ValidationBatch = 0, 0
for images_OneBatchValidation, labels_oneBatchValidation in GetMiniBatches(imageValidation, labelValidation, BATCH_SIZE, shuffle = False):
_, oneBatchTrainAcc = sess.run([train_op, accuracyRate], feed_dict = {x:images_OneBatchValidation, y: labels_oneBatchValidation})
allImagesTrainAcc += oneBatchTrainAcc
n_ValidationBatch += 1
print("Validation,allImagesAcc : %f" % (allImagesTrainAcc / n_ValidationBatch))
print("Train,allImagesLoss: %f" % (allImagesTrainLoss / n_TrainBatch))
print("Train,allImagesAcc : %f" % (allImagesTrainAcc / n_TrainBatch))
if __name__ == '__main__':
train()