头像

NestleLatte

要来一杯拿铁吗

《Tensorflow学习笔记》

 9月前  •   nomad  •     •   368  •   0

博客鸽了好久了,期末考试后紧接着搬家,其实应该还是有时间写的,但每次想起来的时候,我的耳边响起了上古鸽神的低语:“咕咕咕,咕咕咕”。

从周一开始学习Tensorflow,写了三天,实现了一个基于LeNet-5模型的图片分类,收获挺大的。

程序主要分为三部分,第一部分是对图片的处理和送入,实现的比较简单,把图片处理成64*64的三通道数组,一个batch是10.

Pythonimport tensorflow as tf
import os
import numpy as np
def getfile():
    image_all = []
    label_all = []
    i = 0
    for label in os.listdir("./dataset/"):
        for filename in os.listdir(("./dataset/" + label)):
            img = "./dataset/" + label + "/" + filename
            image_all.append(img)
            label_all.append(i)
        i = i + 1
    temp = np.array([image_all, label_all])
    temp = temp.transpose()  # 数组转置
    np.random.shuffle(temp)  # 打乱
    image_list = list(temp[:, 0])
    label_list = list(temp[:, 1])
    label_list = [int(i) for i in label_list]  # 类型转换
    return image_list, label_list

def get_batch(image_list, label_list):
    image = tf.cast(image_list, tf.string)  # 用cast转换为tf类型
    label = tf.cast(label_list, tf.int32)

    input_queue = tf.train.slice_input_producer([image, label])
    label = input_queue[1]
    image_contents = tf.read_file(input_queue[0])

    image = tf.image.decode_jpeg(image_contents, channels=3)  # 解码并标准化处理
    image = tf.image.resize_image_with_crop_or_pad(image, 64, 64)
    image = tf.image.per_image_standardization(image)

    image_batch, label_batch = tf.train.batch([image, label], batch_size=10, num_threads=1, capacity=10)
    label_batch = tf.reshape(label_batch, [10])
    return image_batch, label_batch

第二部分是整个模型的建立,这里使用的是LeNet-5模型

Pythonimport tensorflow as tf

def inference(input_tensor, regularizer):
    # 第一层-卷积层1 输入为64*64*3
    with tf.variable_scope('layer1-conv1'):
        conv1_weights = tf.get_variable(
            "weight", [5, 5, 3, 16],
            initializer=tf.truncated_normal_initializer(stddev=0.1))
        conv1_biases = tf.get_variable("bias", [16], initializer=tf.constant_initializer(0.0))
        conv1 = tf.nn.conv2d(input_tensor, conv1_weights, strides=[1, 1, 1, 1], padding='SAME')
        relu1 = tf.nn.relu(tf.nn.bias_add(conv1, conv1_biases))
    # 第二层-池化层1 输入为64*64*16
    with tf.name_scope("layer2-pool1"):
        pool1 = tf.nn.max_pool(relu1, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding="SAME")
    # 第三层-卷积层2 输入为32*32*16
    with tf.variable_scope("layer3-conv2"):
        conv2_weights = tf.get_variable(
            "weight", [5, 5, 16, 32],
            initializer=tf.truncated_normal_initializer(stddev=0.1))
        conv2_biases = tf.get_variable("bias", [32], initializer=tf.constant_initializer(0.0))
        conv2 = tf.nn.conv2d(pool1, conv2_weights, strides=[1, 1, 1, 1], padding='SAME')
        relu2 = tf.nn.relu(tf.nn.bias_add(conv2, conv2_biases))
    # 第四层-池化层2 输入为32*32*32
    with tf.name_scope("layer4-pool2"):
        pool2 = tf.nn.max_pool(relu2, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding='SAME')
        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])
    # 第五层-全连接层1 输入为16*16*32
    with tf.variable_scope('layer5-fc1'):
        fc1_weights = tf.get_variable("weight", [nodes, 512],
                                      initializer=tf.truncated_normal_initializer(stddev=0.1))
        if regularizer is not None: tf.add_to_collection('losses', regularizer(fc1_weights))
        fc1_biases = tf.get_variable("bias", [512], initializer=tf.constant_initializer(0.1))
        fc1 = tf.nn.relu(tf.matmul(reshaped, fc1_weights) + fc1_biases)
    # 第六层-全连接层2 输入为512*1
    with tf.variable_scope('layer6-fc2'):
        fc2_weights = tf.get_variable("weight", [512, 8],
                                      initializer=tf.truncated_normal_initializer(stddev=0.1))
        if regularizer is not None: tf.add_to_collection('losses', regularizer(fc2_weights))
        fc2_biases = tf.get_variable("bias", [8], initializer=tf.constant_initializer(0.1))
        logit = tf.matmul(fc1, fc2_weights) + fc2_biases
    return logit

第三部分实现反向传播的过程

PythonBATCH_SIZE = 1
LEARNING_RATE_BASE = 0.01
LEARNING_RATE_DECAY = 0.99
REGULARIZATION_RATE = 0.0001
MOVING_AVERAGE_DECAY = 0.99

def train(image_list, label_list):
   # x = tf.placeholder(tf.float32, [100, 64, 64, 3], name='x-input')
   # y_ = tf.placeholder(tf.int32, [None, 8], name='y-input')
    x, y_ = get_batch(image_list, label_list)
    y_ = tf.one_hot(y_, 8)
    regularizer = tf.contrib.layers.l2_regularizer(REGULARIZATION_RATE)
    y = LeNet5_infernece.inference(x, regularizer)
    global_step = tf.Variable(0, trainable=False)

    variable_averages = tf.train.ExponentialMovingAverage(MOVING_AVERAGE_DECAY, global_step)
    variables_averages_op = variable_averages.apply(tf.trainable_variables())

    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'))
    learning_rate = tf.train.exponential_decay(LEARNING_RATE_BASE, global_step, 800, LEARNING_RATE_DECAY, staircase=True)

    train_step = tf.train.GradientDescentOptimizer(learning_rate).minimize(loss, global_step=global_step)
    with tf.control_dependencies([train_step, variables_averages_op]):
        train_op = tf.no_op(name='train')

    with tf.Session() as sess:
        tf.global_variables_initializer().run()
        for i in range(800):
            _, loss_value, step = sess.run([train_op, loss, global_step])
            print("At %d training step(s), loss on training batch is %g." % (step, loss_value))

还好之前对深度学习和Python有些了解,不然真的是头皮发麻。

上一篇:
下一篇:

 评论


 已有0条评论

    还没有任何评论,你来说两句吧!