Tensorflow学习笔记

1.Tensorflow的简单网络。

#coding:utf-8
#0导入模块 ,生成模拟数据集
import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt
BATCH_SIZE = 100
TOTAL_SIZE = 1000

LEARNING_RATE_BASE = 0.1 #最初学习率
LEARNING_RATE_DECAY = 0.5 #学习率衰减率
LEARNING_RATE_STEP = 1000  #喂入多少轮BATCH_SIZE后,更新一次学习率,一般设为:总样本数/BATCH_SIZE

seed = 10
#基于seed产生随机数
rdm = np.random.RandomState(seed)
#随机数返回300行2列的矩阵,表示300组坐标点(x0,x1)作为输入数据集
X = rdm.randn(TOTAL_SIZE,2)
#从X这个300行2列的矩阵中取出一行,判断如果两个坐标的平方和小于2,给Y赋值1,其余赋值0
#作为输入数据集的标签(正确答案)
Y_ = np.array([[int(x0*x0 + x1*x1 <2)] for (x0,x1) in X])
#遍历Y中的每个元素,1赋值'red'其余赋值'blue',这样可视化显示时人可以直观区分
Y_c = [['red' if y else 'blue'] for y in Y_]
#对数据集X和标签Y进行shape整理,第一个元素为-1表示,随第二个参数计算得到,第二个元素表示多少列,把X整理为n行2列,把Y整理为n行1列
#X = np.vstack(X).reshape(-1,2)
#Y_ = np.vstack(Y_).reshape(-1,1)
#print(X)
#print(Y_)
#print(Y_c)
#用plt.scatter画出数据集X各行中第0列元素和第1列元素的点即各行的(x0,x1),用各行Y_c对应的值表示颜色(c是color的缩写)
plt.scatter(X[:, 0], X[:, 1], c=np.squeeze(Y_c))# np.squeeze(Y_c)去掉Y_c.shape中为1的维度
#plt.show()# 显示图

x = tf.placeholder(tf.float32, shape=(None, 2))# 输入占位
y_ = tf.placeholder(tf.float32, shape=(None, 1))# 标签中输出占位

w1 = tf.Variable(tf.random_normal([2, 11]), dtype=tf.float32)# 第一层,2行11列
tf.add_to_collection('losses', tf.contrib.layers.l2_regularizer(0.01)(w1))# 将w1的正则化加入‘losses’中
b1 = tf.Variable(tf.constant(0.01, shape=[11]))# 第一层偏置
y1 = tf.nn.relu(tf.matmul(x, w1)+b1)# 激活函数relu,y1为神经网络第一层的输出

w2 = tf.Variable(tf.random_normal([11, 1]), dtype=tf.float32)# 第二层,11行1列
tf.add_to_collection('losses', tf.contrib.layers.l2_regularizer(0.01)(w2))# w2的正则化
b2 = tf.Variable(tf.constant(0.01, shape=[1]))# w2的偏置
y = tf.matmul(y1, w2)+b2# 网络的输出

global_step = tf.Variable(0, trainable=False)# 迭代步数,计数器
#定义指数下降学习率
learning_rate = tf.train.exponential_decay(LEARNING_RATE_BASE, global_step, LEARNING_RATE_STEP, LEARNING_RATE_DECAY, staircase=True)# 学习率的衰减方式为指数方式
loss_mse = tf.reduce_mean(tf.square(y-y_))# 误差平均差,损失函数
loss_total = loss_mse + tf.add_n(tf.get_collection('losses'))# 总的损失函数

train_step = tf.train.AdamOptimizer(learning_rate).minimize(loss_total, global_step=global_step)# 定义每一步迭代,使用的优化器为Adam,

with tf.Session() as sess:
    init_op = tf.global_variables_initializer()# 初始化变量
    sess.run(init_op)
    for i in range(10000):# 开始迭代
        start = (i * BATCH_SIZE)% TOTAL_SIZE# BATCH_SIZE下,计算每一次迭代的数据的BATCH的第一个位置
        end = start + BATCH_SIZE# 每一次迭代的结尾,配合start
        sess.run(train_step, feed_dict={x: X[start:end], y_: Y_[start:end]})# 执行训练一次,需要feed的参数为训练集的x,和标签。
        if i % 500 == 0:# 每迭代500次执行一次
            print("step: ",i," global_step: ",sess.run(global_step)," learning_rate ",sess.run(learning_rate)," loss: ",sess.run(loss_mse, feed_dict={x: X[start:end], y_: Y_[start:end]}))
    #xx在-3到3之间以步长为0.01,yy在-3到3之间以步长0.01,生成二维网格坐标点
    xx, yy = np.mgrid[-5:5:.01, -5:5:.01]# 实际上就是将网格切分,xx和yy中记录的都是[-5,5]步长为0.01的10000个数,
    #print("xx.shape: ",xx.shape)
    # 将xx , yy拉直,并合并成一个2列的矩阵,得到一个网格坐标点的集合
    grid = np.c_[xx.ravel(), yy.ravel()]# 形成类似于[xx,yy]的二维矩阵。np.c_将两个矩阵横向相加,要求行数相等。纵向相加的对应的是np.r_
    #print("grid.shape: ",grid.shape)
    # 将网格坐标点喂入神经网络 ,probs为输出
    probs = sess.run(y, feed_dict={x: grid})
    #print("probs.shape: ",probs.shape)
    # probs的shape调整成xx的样子
    probs = probs.reshape(xx.shape)
    #print("w1:\n", sess.run(w1))
    #print("b1:\n", sess.run(b1))
    #print("w2:\n", sess.run(w2))
    #print("b2:\n", sess.run(b2))

a = plt.contourf(xx, yy, probs, 100, cmap=plt.cm.Spectral)# 把输出划分为100个等级,填充颜色
plt.scatter(X[:, 0], X[:, 1], c=np.squeeze(Y_c))# 画原数据点
b = plt.contour(xx, yy, probs, levels=[.5])# 画等高线
plt.colorbar(a, ticks=[0, 0.5, 1, 1.5, 2.0, 2.5])# 右侧数据条
plt.clabel(b, inline=True, fontsize=10)# 显示等高线
plt.show()# 显示

10000次迭代后输出结果:
在这里插入图片描述

2.训练mnist数据集(不用卷积)

训练代码:

import numpy as np
import tensorflow as tf
from tensorflow.examples.tutorials.mnist import input_data
import os

BATCH_SIZE = 200
LEARNING_RATE_BASE = 0.1
LEARNING_RATE_DECAY = 0.99
MOVING_AVERAGE_DECAY = 0.99
STEPS = 50000
REGULARIZER = 0.0001
OUTPUT_NODE = 10
INPUT_NODE = 784
HIDDEN_NODE = 500

MODEL_SAVE_PATH = "./models/"# 模型保存的路径
MODEL_NAME = "mnist_model"# 模型保存名字
DATA_PATH = "/home/yjh/Tensorflow-learning/Tensorflow5fc1/data"# 数据集路径


def get_weight(shape, regularizer):# 添加一个w层
    w = tf.Variable(tf.truncated_normal(shape, stddev=0.1))# 生成随机数方式为截断正态分布
    if regularizer != None:# 判断是否带正则化
        tf.add_to_collection("losses", tf.contrib.layers.l2_regularizer(regularizer)(w))
    return w


def get_bias(shape):# 生成一个偏置项
    b = tf.Variable(tf.zeros(shape))# 偏置初始化为0
    return b

mnist = input_data.read_data_sets(DATA_PATH, one_hot=True)# 获取数据集

x = tf.placeholder(tf.float32, [None, INPUT_NODE])# 输入占位,长度为一个一个数据的长度。
y_ = tf.placeholder(tf.float32, [None, OUTPUT_NODE])# 标签的占位,长度为10分类

w1 = get_weight([INPUT_NODE, HIDDEN_NODE], REGULARIZER)# 网络的第一层
b1 = get_bias([HIDDEN_NODE])# 第一层的偏置
y1 = tf.nn.relu(tf.matmul(x, w1) + b1)# 第一层的输出

w2 = get_weight([HIDDEN_NODE, OUTPUT_NODE], REGULARIZER)# 第二层
b2 = get_bias([OUTPUT_NODE])# 第二层偏置
y = tf.matmul(y1, w2) + b2# 输出

global_step = tf.Variable(0, trainable=False)# 迭代步数计数器
ce = tf.nn.sparse_softmax_cross_entropy_with_logits(logits=y, labels=tf.argmax(y_, 1))# 对网络最后一层的输出y做softmax,在根据标签求交叉熵
cem = tf.reduce_mean(ce)# 均值loss
loss = cem + tf.add_n(tf.get_collection("losses"))# 总loss,加上了正则化

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.MomentumOptimizer(learning_rate, 0.9).minimize(loss, global_step=global_step)# 优化器为Mumentum

ema = tf.train.ExponentialMovingAverage(MOVING_AVERAGE_DECAY, global_step)# 指数滑动平均
ema_op = ema.apply(tf.trainable_variables())# 使用滑动平均

with tf.control_dependencies([train_step, ema_op]):# 依赖
    train_op = tf.no_op(name='train')# 当sess.run(train_op)时,会同时run上边两个[train_step, ema_op]

saver = tf.train.Saver()# 建立一个保存模型的存储器

with tf.Session() as sess:
    init_op = tf.global_variables_initializer()
    sess.run(init_op)
    for i in range(STEPS):
        xs, ys = mnist.train.next_batch(BATCH_SIZE)# 在训练集中提取一个BATCH
        _, loss_value, step = sess.run([train_op, loss, global_step], feed_dict={x: xs, y_: ys})
        if (i + 1) % 1000 == 0:
            print("after %d steps, ;loss is %f" % (step, loss_value))
            if (i + 1) % 5000 == 0:
                saver.save(sess, os.path.join(MODEL_SAVE_PATH, MODEL_NAME), global_step=global_step)

pycharm运行结果:

after 1000 steps, ;loss is 0.170276
after 2000 steps, ;loss is 0.136261
after 3000 steps, ;loss is 0.115604
after 4000 steps, ;loss is 0.105963
after 5000 steps, ;loss is 0.088661
after 6000 steps, ;loss is 0.081842
after 7000 steps, ;loss is 0.073383
after 8000 steps, ;loss is 0.068116
after 9000 steps, ;loss is 0.064231
after 10000 steps, ;loss is 0.061444
after 11000 steps, ;loss is 0.054349
after 12000 steps, ;loss is 0.049520
after 13000 steps, ;loss is 0.050399
after 14000 steps, ;loss is 0.046730
after 15000 steps, ;loss is 0.046526
after 16000 steps, ;loss is 0.042283
after 17000 steps, ;loss is 0.043034
after 18000 steps, ;loss is 0.039838
after 19000 steps, ;loss is 0.038359
after 20000 steps, ;loss is 0.039458
after 21000 steps, ;loss is 0.036007
after 22000 steps, ;loss is 0.037945
after 23000 steps, ;loss is 0.035751
after 24000 steps, ;loss is 0.037602
after 25000 steps, ;loss is 0.035550
after 26000 steps, ;loss is 0.036474
after 27000 steps, ;loss is 0.032806
after 28000 steps, ;loss is 0.033995
after 29000 steps, ;loss is 0.032326
after 30000 steps, ;loss is 0.031818
after 31000 steps, ;loss is 0.035270
after 32000 steps, ;loss is 0.035549
after 33000 steps, ;loss is 0.030204
after 34000 steps, ;loss is 0.033483
after 35000 steps, ;loss is 0.032387
after 36000 steps, ;loss is 0.032469
after 37000 steps, ;loss is 0.031001
after 38000 steps, ;loss is 0.033947
after 39000 steps, ;loss is 0.031707
after 40000 steps, ;loss is 0.029635
after 41000 steps, ;loss is 0.030342
after 42000 steps, ;loss is 0.029521
after 43000 steps, ;loss is 0.032588
after 44000 steps, ;loss is 0.028240
after 45000 steps, ;loss is 0.031453
after 46000 steps, ;loss is 0.031022
after 47000 steps, ;loss is 0.028289
after 48000 steps, ;loss is 0.031529
after 49000 steps, ;loss is 0.029671
after 50000 steps, ;loss is 0.030248

3.使用Lenet5卷积神经网络,实现手写图数字识别,包括训练和单张测试函数

import tensorflow as tf
import numpy as np
import os
import time
from PIL import Image
from tensorflow.examples.tutorials.mnist import input_data

BATCH_SIZE = 1
IMAGE_SIZE = 28# 图像的WH都是38
IMAGE_CHANNELS = 1# 输入图像为单通道图像
KERNEL_SIZE1 = 5# 第一个卷积核的长宽
CONV1_CHANNEL_NUM = 32# 第一次卷积后的特征图通道个数
KERNEL_SIZE2 = 5# 第二次卷积卷积核的大小
CONV2_CHANNEL_NUM = 64# 第二次卷积后的特征图通道数
OUTPUT_NODE = 10# 输出10类
FC_SIZE = 512# 全连接层的大小
REGULARIZER = 0.0001# 正则化参数
LEARNING_RATE_DECAY = 0.99# 学习率的衰减率
LEARNING_RATE_BASE = 0.005# 基础学习率
MOVING_AVERAGE_DECAY = 0.99# 滑动平均的参数
MODEL_SAVE_PATH = "./model/"# 模型保存路径
MODEL_NAME = "mnist_model"# 模型保存名称


def net_build(x_size):# 构建网络
    # 第一层
    x = tf.placeholder(tf.float32, [x_size,
                                    IMAGE_SIZE,
                                    IMAGE_SIZE,
                                    IMAGE_CHANNELS])# 输入占位,
    conv1_w = tf.Variable(tf.truncated_normal([KERNEL_SIZE1,
                                               KERNEL_SIZE1,
                                               IMAGE_CHANNELS,
                                               CONV1_CHANNEL_NUM], stddev=0.1))# 定义第一个卷积核
    tf.add_to_collection('losses', tf.contrib.layers.l2_regularizer(REGULARIZER)(conv1_w))# 添加正则化
    conv1_b = tf.Variable(tf.zeros([CONV1_CHANNEL_NUM]))# 第一层卷积偏置
    conv1 = tf.nn.conv2d(x, conv1_w, strides=[1, 1, 1, 1], padding='SAME')# 卷积,步长为1,方式为全padding
    relu1 = tf.nn.relu(tf.nn.bias_add(conv1, conv1_b))# 添加偏置后,进行激活函数
    pool1 = tf.nn.max_pool(relu1, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding='SAME')# 最大池化层,核大小为2,步长为2
    # 第二层
    conv2_w = tf.Variable(tf.truncated_normal([KERNEL_SIZE2,
                                               KERNEL_SIZE2,
                                               CONV1_CHANNEL_NUM,
                                               CONV2_CHANNEL_NUM], stddev=0.1))#第二次卷积核
    tf.add_to_collection('losses', tf.contrib.layers.l2_regularizer(REGULARIZER)(conv2_w))# 正则化
    conv2_b = tf.Variable(tf.zeros([CONV2_CHANNEL_NUM]))# 偏置
    conv2 = tf.nn.conv2d(pool1, conv2_w, strides=[1, 1, 1, 1], padding='SAME')# 卷积,步长为1,padding
    relu2 = tf.nn.relu(tf.nn.bias_add(conv2, conv2_b))# 卷积后加偏置并激活
    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()# 得到第二次卷积后的特征图shape,放到一个列表中,列表的0、1、2、3个分别是,B,H,W,C(不确定顺序)
    nodes = pool_shape[1] * pool_shape[2] * pool_shape[3]# 得到一个特征图的像素点数量
    reshaped = tf.reshape(pool2, [pool_shape[0], nodes])# 将卷基层输出的所有特征图都拉直,得到的维度为[一个特征图像素点数,BATCH]

    fc1_w = tf.Variable(tf.truncated_normal([nodes, FC_SIZE], stddev=0.1))# 第一层全连接层
    tf.add_to_collection('losses', tf.contrib.layers.l2_regularizer(REGULARIZER)(fc1_w))# 正则化
    fc1_b = tf.Variable(tf.zeros([FC_SIZE]))# 第一层全连接的偏置
    fc1 = tf.matmul(reshaped, fc1_w) + fc1_b# 计算
    fc1_rule = tf.nn.relu(fc1)#激活
    fc1_dropout = tf.nn.dropout(fc1_rule, 0.5)# dropout,概率为0.5
    fc2_w = tf.Variable(tf.truncated_normal([FC_SIZE, OUTPUT_NODE], stddev=0.1))# 第二层全连接
    tf.add_to_collection('losses', tf.contrib.layers.l2_regularizer(REGULARIZER)(fc2_w))# 正则化
    fc2_b = tf.Variable(tf.zeros([OUTPUT_NODE]))# 第二层偏置
    y = tf.matmul(fc1_dropout, fc2_w) + fc2_b# 输出
    return x, y# 返回输入和输出


def train():# 训练过程
    mnist_data = input_data.read_data_sets("./data/", one_hot=True)# 读取mnist的数据集
    x_ph, y_ph = net_build(BATCH_SIZE)# 建立网络,定义前向传播过程
    y_label = tf.placeholder(tf.float32, [None, OUTPUT_NODE])# 训练集标签的占位
    global_step = tf.Variable(0, trainable=False)# 总的训练计数器
    ce = tf.nn.sparse_softmax_cross_entropy_with_logits(logits=y_ph, labels=tf.argmax(y_label, 1))# 对前向传播的结果y_ph做softmax(求出分类的概率),并求出交叉熵
    cem = tf.reduce_mean(ce)# 求平均值
    loss = cem + tf.add_n(tf.get_collection('losses'))# 计算损失函数
    learning_rate = tf.train.exponential_decay(
            LEARNING_RATE_BASE,
            global_step,
            mnist_data.train.num_examples / BATCH_SIZE,
            LEARNING_RATE_DECAY,
            staircase=True)# 学习率指数衰减
    # train_step = tf.train.MomentumOptimizer(learning_rate, 0.9).minimize(loss, global_step=global_step)# 选择优化器
    train_step = tf.train.GradientDescentOptimizer(learning_rate).minimize(loss, global_step=global_step)
    ema = tf.train.ExponentialMovingAverage(MOVING_AVERAGE_DECAY, global_step)# 指数滑动平均
    ema_op = ema.apply(tf.trainable_variables())# 应用滑动平均
    with tf.control_dependencies([train_step, ema_op]):# train_step和ema_op合并到以一个列表,合成一个操作
        train_op = tf.no_op(name='train')
    with tf.Session() as sess:
        init_op = tf.global_variables_initializer()# 初始化变量
        sess.run(init_op)
        ckpt = tf.train.get_checkpoint_state(MODEL_SAVE_PATH)# 加载检查点
        saver = tf.train.Saver()# 模型的存储器
        if ckpt and ckpt.model_checkpoint_path:# 检查是否存在训练的检查点
            saver.restore(sess, ckpt.model_checkpoint_path)# 有的话加载存贮的模型的检查点,一会继续训练
            print("ckpt done.")
            time.sleep(1)# 暂停一秒。为的是让人看清楚上面打印的话
        for i in range(50000):# 开始训练迭代50000次
            xs, ys = mnist_data.train.next_batch(BATCH_SIZE)  #取一个BATCH
            reshaped_xs = np.reshape(xs, (
                BATCH_SIZE,
                IMAGE_SIZE,
                IMAGE_SIZE,
                IMAGE_CHANNELS))  # 把训练集输入拉直
            _, loss_value, step, lr = sess.run([train_op, loss, global_step, learning_rate], feed_dict={x_ph: reshaped_xs, y_label: ys})# 训练

            if (i+1) % 10000 == 0:  # 每迭代10000次保存一次结果
                print("After %d training step(s),lr %f; loss on training batch is %g." % (step, lr, loss_value))
                saver.save(sess, os.path.join(MODEL_SAVE_PATH, MODEL_NAME), global_step=global_step)

            if (i+1) % 100 == 0:
                print("After %d training step(s),lr %f; loss on training batch is %g." % (step, lr, loss_value))


# 预处理图片
def pre_pic(picName):  # 图片预处理,预处理自己的图片
    img = Image.open(picName)  # 打开图片,用的是PIL
    reIm = img.resize((28, 28), Image.ANTIALIAS)  # 将图片拉伸为28*28大小,质量为Image.ANTIALIAS
    im_arr = np.array(reIm.convert('L'))  # 转化为灰度图
    threshold = 50  # 定义一个阈值,低于阈值的将被省略
    for i in range(28):  # 遍历图像,进行二值化
        for j in range(28):
            im_arr[i][j] = 255 - im_arr[i][j]
            if (im_arr[i][j] < threshold):
                im_arr[i][j] = 0
            else: im_arr[i][j] = 255
    # 将图片转换为需要的四个张量
    nm_arr = im_arr.reshape([1,
                             IMAGE_SIZE,
                             IMAGE_SIZE,
                             IMAGE_CHANNELS])  # 将二值化的图片转化为张量
    nm_arr = nm_arr.astype(np.float32)  # 张量转为float32形式
    img_ready = np.multiply(nm_arr, 1.0/255.0)  # 像素值限定到0-1

    return img_ready  # 最后返回的是一个28*28*1的二值化图


def test():  # 测试训练结果的函数
    with tf.Graph().as_default() as g:  # 在默认图下建立网络
        x_ph, y_ph = net_build(1)  # 定义网络,生成前向传播
        preSotfmax = tf.nn.softmax(y_ph)  # 对结果进行非极大值抑制,得出分类结果
        preValue = tf.argmax(preSotfmax, 1)  # 找出top1,即可能性最大的结果
        pic_array = pre_pic('./5.jpg')  # 进行图片预处理,得出可供训练的图片数据格式
        #print(pic_array.shape)
        with tf.Session() as sess:
            ckpt = tf.train.get_checkpoint_state(MODEL_SAVE_PATH)  # 模型路径
            saver = tf.train.Saver()  # 定义存储器
            if ckpt and ckpt.model_checkpoint_path:  # 如果模型存在
                saver.restore(sess, ckpt.model_checkpoint_path)  # 加载模型
                out_y, output_val, output_softmax = sess.run([y_ph, preValue, preSotfmax], feed_dict={x_ph: pic_array})  # 将图片喂给网络,进行预测
                print('网络的输出out_y: \n',out_y)
                print('分类结果output_softmax: \n',output_softmax)
                print(output_val)


def main():
    print('main')
    test()


if __name__ == '__main__':
    main()

输入图片:
在这里插入图片描述
输出结果:

网络的输出out_y: 
 [[-6.7819757  -0.47882637 -0.52103394  5.084658   -5.0194373  10.814644
  -1.8547115  -1.8722407   5.6790185   0.9596205 ]]
分类结果output_softmax: 
 [[2.2589280e-08 1.2340278e-05 1.1830261e-05 3.2174783e-03 1.3163231e-07
  9.9087030e-01 3.1173508e-06 3.0631813e-06 5.8296579e-03 5.2003736e-05]]
属于类别:output_val: 
 [5]
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值