TF练习3 以图片形式读取Mnist,复现Lenet各层模型,分类手写体

一直都很困扰,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()
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值