Python_2019-01-04_机器学习——Tensorflow基本实现

目录

tensorflow基础

张量 

Tensor to Numpy'ndarray

numpy'ndarray to tensor

Tensorflow(tf)、matplotlib.pyplot(plt)

案例:求y=(3*x1+4*x2) ^2在(2,3)处的偏导(梯度:(F'x1、F'x2))

三个参数:张量、常量、占位符、变量

案例——求极小值

案例——梯度下降求最小值点

案例——单图输入(卷积、偏置、激活、池化、拉伸示例)

案例——多图输入(卷积、偏置、激活、池化、拉伸示例)

示例:制作tfrecord数据

封装子程序

tensorflow实验

打包exe识别模型(训练好的)——测试成功

VGG16_tfrecords_17分类

随意定义一个卷积网络进行四分类

编译器的操作

cnn 2分类 

CNN 多分类

tensorflow基础

张量 

# coding=utf-8

''' 
Copyright 2019
License()
Author:
This is ...
'''
import tensorflow as tf
print(tf.__version__)

# constant
t = tf.constant([1,1,2], tf.float32)
# 打印张量信息而已,如尺寸、类型等
print(t)

Tensor to Numpy'ndarray

# coding=utf-8

''' 
Copyright 2019
License()
Author:
This is ...
'''
import tensorflow as tf
print(tf.__version__)

# constant
t = tf.constant([1,1,2], tf.float32)

'''
Tensor转ndarray
方法一:
'''
# 创建会话
session = tf.Session()
# 张量转Numpy的数据结构ndarray
array = session.run(t)
print(type(array))
print(array)
'''
Tensor转ndarray
方法二:
'''
session = tf.Session()
array = t.eval(session = session)
print(array)

numpy'ndarray to tensor

# coding=utf-8

''' 
Copyright 2019
License()
Author:
This is ...
'''
import tensorflow as tf
import numpy as np

print(tf.__version__)
print(np.__version__)

array = np.array([1,2,3], np.float32)
t = tf.convert_to_tensor(array,tf.float32,name='t')
print(t)

Tensorflow(tf)、matplotlib.pyplot(plt)

# coding=utf-8

''' 
Copyright 2019
License()
Author:
This is ...
'''
import tensorflow as tf
import matplotlib.pyplot as plt
import numpy as np

print(tf.__version__)
print(np.__version__)

# "图片文件解码为Tensor"
image = tf.read_file("test.png", 'r')
image_tensor = tf.image.decode_jpeg(image)

# "图片张量的形状"
shape = tf.shape(image_tensor)

# Tensor转ndarray
session = tf.Session()
image_ndarray = image_tensor.eval(session=session)

# 显示ndarray
plt.imshow(image_ndarray)
plt.show()

案例:求y=(3*x1+4*x2) ^2在(2,3)处的偏导(梯度:(F'x1、F'x2))

# coding=utf-8
''' 
Copyright 2019
License()
Author:
This is ...
求 Y = (3*X1+4*X2)^2 在(3,2)处的偏导
[3,4]*[X1,X2]'
'''
import tensorflow as tf
import numpy as np
# 常量
w = tf.constant([[3,4]], tf.float32)
# 传入变量
x = tf.placeholder(tf.float32, (2,1))
# w*x
y = tf.matmul(w, x)
# 平方和
F = tf.pow(y, 2)
# 求梯度
grads = tf.gradients(F, x)

# 会话
session = tf.Session()
print(session.run(grads, {x:np.array([[2],[3]])}))

三个参数:张量、常量、占位符、变量

占位符:占位符是计算图等着喂数据的地方。告诉系统这里会有一个这种格式的张量,但是还没有传入具体的值。

常量:不可更改的张量。

变量:

输入输出数据在tf中是用placeholder占位符来定义的,网络参数是用tf.Variable来定义的。

y=3*x1+4*x2——》[3,4]*[x1,x2]'——》张量[3,4]、占位符[x1,x2]

y=w*x——》[w]*[x]——》变量[w]、占位符[x]

# 占位符
x = tf.placeholder(tf.float32,[2,none],name='x')
x = tf.placeholder(tf.float32,(2,1))

# 常量\张量
x = tf.constant([1,2,3],tf.float32)

# 变量————创建Variable对象
x = tf.Variable(tf.constant([2,3],tf.float32))
session = tf.Session()
# 必须进行初始化,才能使用Variable对象的值
session.run(tf.global_variable_initializer())

案例——求极小值

# coding=utf-8
''' 
Copyright 2019
License()
Author:
This is ...
求 Y = (X-1)^2 的最小值点
X:变量、Y(X)函数、利用梯度下降求最小值的点
'''
import tensorflow as tf
import numpy as np

x = tf.Variable(4, dtype=tf.float32)
y = tf.pow(x-1, 2)

poti = tf.train.GradientDescentOptimizer(0.25).minimize(y)

session = tf.Session()
session.run(tf.global_variables_initializer())

for i in range(3):
	session.run(poti)
	print(session.run(x))

案例——梯度下降求最小值点

# coding=utf-8
''' 
Copyright 2019
License()
Author:
This is ...
求 Y = (X-1)^2 的最小值点
X:变量、 Y(X) 函数、利用梯度下降求最小值的点
'''
import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt
import math

x = tf.Variable(20, dtype=tf.float32)
y = tf.pow(x-1, 2)

poti = tf.train.GradientDescentOptimizer(0.001).minimize(y)

# "画 y(x) 的曲线 y_value — value "
value = np.arange(-15, 17, 0.01)
y_value = np.power(value-1, 2.0)
plt.plot(value, y_value)


# "创建会话"
session = tf.Session()
session.run(tf.global_variables_initializer())

for i in range(1000):
	session.run(poti)
	if(i%10 == 0):
		v = session.run(x)
		plt.plot(v, math.pow(v-1, 2.0), 'go')
		print('第 %d 次迭代: %f'%(i+1, v))
plt.show()

案例——单图输入(卷积、偏置、激活、池化、拉伸示例)

# coding=utf-8
''' 
Copyright 2019
License()
Author:
This is ...
图*卷积核+偏置+激活+池化+拉伸
'''
import tensorflow as tf
# 输入
# 1个【】,各包含3个【】,*各包含3个【】, *各包含2个值
# 尺寸:1*3*3*2
input_tensor = tf.constant(
	[
		[ 
			[ 
				[2,5], 
				[3,3], 
				[8,2] 
			],
			[ 
				[6,1], 
				[1,2], 
				[5,4] 
			],
			[ 
				[7,9],
				[2,8], 
				[1,3] 
			]
		]
	], tf.float32)
print(input_tensor)
session = tf.Session()
print(session.run(input_tensor))

# 卷积核
# 2【】,*各包含2【】,*各包含2【】,*各包含3值
# 尺寸:2*2*2*3
kernel = tf.constant(
	[
		[
			[
				[-1,1,0],
				[1,-1,-1]
			],
			[
				[0,0,-1],
				[0,0,0]
			]
		],
		[
			[
				[0,0,0],
				[0,0,1]
			],
			[
				[1,-1,1],
				[-1,1,0]
			]
		]
	],tf.float32
	)
print(kernel)
session = tf.Session()
print(session.run(kernel))

# 卷积
conv2d = tf.nn.conv2d(input_tensor, kernel, (1, 1, 1, 1), 'SAME')
print(conv2d)
session = tf.Session()
print(session.run(conv2d))

# 偏置
bias = tf.constant([1, 2, 3], tf.float32)
conv2d_add_bias = tf.add(conv2d, bias)
print(conv2d_add_bias)

# 激活
active = tf.nn.relu(conv2d_add_bias)
print(active)

# 池化
active_maxPool = tf.nn.max_pool(active, (1,2,2,1), (1,1,1,1), 'VALID')
print(active_maxPool)

# 拉伸(shape的长、宽、高)
shape = active_maxPool.get_shape()
num = shape[1].value*shape[2].value*shape[3].value
flatten = tf.reshape(active_maxPool, [-1,num])

# 打印结果
session = tf.Session()
print(session.run(flatten))

案例——多图输入(卷积、偏置、激活、池化、拉伸示例)

# coding=utf-8
''' 
Copyright 2019
License()
Author:
This is ...
多个图*卷积核+偏置+激活+池化+拉伸
'''
import tensorflow as tf
import numpy as np
# 输入
# 1个【】,各包含3个【】,*各包含3个【】, *各包含2个值
# 尺寸:1*3*3*2
input_tensor = tf.placeholder(tf.float32, [None, 3, 3, 2])


# 卷积核
# 2【】,*各包含2【】,*各包含2【】,*各包含3值
# 尺寸:2*2*2*3
kernel = tf.constant(
	[
		[
			[
				[-1,1,0],
				[1,-1,-1]
			],
			[
				[0,0,-1],
				[0,0,0]
			]
		],
		[
			[
				[0,0,0],
				[0,0,1]
			],
			[
				[1,-1,1],
				[-1,1,0]
			]
		]
	],tf.float32
	)
print(kernel)
session = tf.Session()
print(session.run(kernel))

# 卷积
conv2d = tf.nn.conv2d(input_tensor, kernel, (1, 1, 1, 1), 'SAME')

# 偏置
bias = tf.constant([1, 2, 3], tf.float32)
conv2d_add_bias = tf.add(conv2d, bias)
print(conv2d_add_bias)

# 激活
active = tf.nn.relu(conv2d_add_bias)
print(active)

# 池化
active_maxPool = tf.nn.max_pool(active, (1,2,2,1), (1,1,1,1), 'VALID')
print(active_maxPool)

# 拉伸(shape的长、宽、高)
shape = active_maxPool.get_shape()
num = shape[1].value*shape[2].value*shape[3].value
flatten = tf.reshape(active_maxPool, [-1,num])

# 打印结果
session = tf.Session()
print(session.run(flatten, feed_dict={input_tensor:np.array(
	[
		[
		[[2,5],[3,3],[3,3]],
		[[3,3],[3,3],[3,3]],
		[[3,3],[3,33],[3,3]]
		],
		[
		[[3,3],[3,3],[3,3]],
		[[3,43],[23,3],[3,3]],
		[[3,3],[3,3],[3,3]]
		],
		[
		[[3,53],[13,3],[3,3]],
		[[3,73],[3,3],[3,3]],
		[[3,3],[3,83],[3,3]]
		]
	]
	)}))



示例:制作tfrecord数据

data里面有:

#coding=utf-8
''' 
Copyright 2019
License()
Author:
This is ...
创建 tfrecord 类型的数据流
'''
import os
import tensorflow as tf
from PIL import Image

imgpath = '.\\data\\'
# 当前文件夹
cwd = os.getcwd()
# 指定文件夹的子文件夹名【'**','**'】
classes = os.listdir(cwd + imgpath)
# 创建 TFRecordWriter对象 和 "train.tfrecords"文件
writer = tf.python_io.TFRecordWriter("train.tfrecords")
for index, name in enumerate(classes):
	# index:第几个{0,1,...}
	print(index)
	# name:子文件夹的名称{**,**,**,...}
	print(name)
	# 每类图的绝对路径
	class_path = cwd + imgpath + name + "\\"
	print(class_path)
	if os.path.isdir(class_path):
		for img_name in os.listdir(class_path):
			print(img_name)
			img_path = class_path + img_name
			# 读取每个图片并进行尺寸调整
			image = Image.open(img_path)
			image = image.resize((224, 224))
			# "二进制化"
			img_raw = image.tobytes()
			# "存储内容设置"
			example = tf.train.Example(
				features=
				tf.train.Features(
					feature=
					{
					'label': tf.train.Feature(int64_list=tf.train.Int64List(value=[int(name)])),
					'img_raw': tf.train.Feature(bytes_list=tf.train.BytesList(value=[img_raw]))
					}#特征序列为:标签+图片数据
					)
				)
			# "字符串序列化后写入文件"
			writer.write(example.SerializeToString())
# 关闭文件流
writer.close()

封装子程序

#coding=utf-8
''' 
Copyright 2019
License()
Author:
This is ...
创建 tfrecord 类型的数据流
'''
import os
import tensorflow as tf
from PIL import Image


def creat_tfrecord(imgpath):
	# 当前文件夹
	cwd = os.getcwd()
	# 指定文件夹的子文件夹名【'**','**'】
	classes = os.listdir(cwd + imgpath)
	# 创建 TFRecordWriter对象 和 "train.tfrecords"文件
	writer = tf.python_io.TFRecordWriter("train.tfrecords")
	for index, name in enumerate(classes):
		# index:第几个{0,1,...}
		print(index)
		# name:子文件夹的名称{**,**,**,...}
		print(name)
		# 每类图的绝对路径
		class_path = cwd + imgpath + name + "\\"
		print(class_path)
		if os.path.isdir(class_path):
			for img_name in os.listdir(class_path):
				print(img_name)
				img_path = class_path + img_name
				# 读取每个图片并进行尺寸调整
				image = Image.open(img_path)
				image = image.resize((224, 224))
				# "二进制化"
				img_raw = image.tobytes()
				# "存储内容设置"
				example = tf.train.Example(
					features=
					tf.train.Features(
						feature=
						{
						'label': tf.train.Feature(int64_list=tf.train.Int64List(value=[int(name)])),
						'img_raw': tf.train.Feature(bytes_list=tf.train.BytesList(value=[img_raw]))
						}#特征序列为:标签+图片数据
						)
					)
				# "字符串序列化后写入文件"
				writer.write(example.SerializeToString())
	# 关闭文件流
	writer.close()
if __name__ == '__main__':
    imgpath = '.\\data\\'
    creat_tfrecord(imgpath)



tensorflow实验

打包exe识别模型(训练好的)——测试成功

'''
第一步:主函数
    功能:
        利用训练好的模型,进行实时手写体识别
    作者:yuhansgg
    博客: https://blog.csdn.net/u011389706
    日期: 2018/08/06
'''
import sys
from PyQt5.QtWidgets import QApplication
from MyMnistWindow import MyMnistWindow
sys.setrecursionlimit(5000)
if __name__ == "__main__":
    app = QApplication(sys.argv)
    mymnist = MyMnistWindow()
    mymnist.show()
    app.exec_()
'''
第二步:界面
    功能:
        利用训练好的模型,进行实时手写体识别
    作者:yuhansgg
    博客: https://blog.csdn.net/u011389706
    日期: 2018/08/06
'''
import tensorflow as tf
from PyQt5.QtWidgets import (QWidget, QPushButton, QLabel)
from PyQt5.QtGui import (QPainter, QPen, QFont)
from PyQt5.QtCore import Qt
from PIL import ImageGrab, Image

class MyMnistWindow(QWidget):

    def __init__(self):
        super(MyMnistWindow, self).__init__()

        self.resize(284, 330)  # resize设置宽高
        self.move(100, 100)    # move设置位置
        self.setWindowFlags(Qt.FramelessWindowHint)  # 窗体无边框
        #setMouseTracking设置为False,否则不按下鼠标时也会跟踪鼠标事件
        self.setMouseTracking(False)

        self.pos_xy = []  #保存鼠标移动过的点

        # 添加一系列控件
        self.label_draw = QLabel('', self)
        self.label_draw.setGeometry(2, 2, 280, 280)
        self.label_draw.setStyleSheet("QLabel{border:1px solid black;}")
        self.label_draw.setAlignment(Qt.AlignCenter)

        self.label_result_name = QLabel('识别结果:', self)
        self.label_result_name.setGeometry(2, 290, 60, 35)
        self.label_result_name.setAlignment(Qt.AlignCenter)

        self.label_result = QLabel(' ', self)
        self.label_result.setGeometry(64, 290, 35, 35)
        self.label_result.setFont(QFont("Roman times", 8, QFont.Bold))
        self.label_result.setStyleSheet("QLabel{border:1px solid black;}")
        self.label_result.setAlignment(Qt.AlignCenter)

        self.btn_recognize = QPushButton("识别", self)
        self.btn_recognize.setGeometry(110, 290, 50, 35)
        self.btn_recognize.clicked.connect(self.btn_recognize_on_clicked)

        self.btn_clear = QPushButton("清空", self)
        self.btn_clear.setGeometry(170, 290, 50, 35)
        self.btn_clear.clicked.connect(self.btn_clear_on_clicked)

        self.btn_close = QPushButton("关闭", self)
        self.btn_close.setGeometry(230, 290, 50, 35)
        self.btn_close.clicked.connect(self.btn_close_on_clicked)

    def paintEvent(self, event):
        painter = QPainter()
        painter.begin(self)
        pen = QPen(Qt.black, 30, Qt.SolidLine)
        painter.setPen(pen)

        '''
            首先判断pos_xy列表中是不是至少有两个点了
            然后将pos_xy中第一个点赋值给point_start
            利用中间变量pos_tmp遍历整个pos_xy列表
                point_end = pos_tmp

                判断point_end是否是断点,如果是
                    point_start赋值为断点
                    continue
                判断point_start是否是断点,如果是
                    point_start赋值为point_end
                    continue

                画point_start到point_end之间的线
                point_start = point_end
            这样,不断地将相邻两个点之间画线,就能留下鼠标移动轨迹了
        '''
        if len(self.pos_xy) > 1:
            point_start = self.pos_xy[0]
            for pos_tmp in self.pos_xy:
                point_end = pos_tmp

                if point_end == (-1, -1):
                    point_start = (-1, -1)
                    continue
                if point_start == (-1, -1):
                    point_start = point_end
                    continue

                painter.drawLine(point_start[0], point_start[1], point_end[0], point_end[1])
                point_start = point_end
        painter.end()

    def mouseMoveEvent(self, event):
        '''
            按住鼠标移动事件:将当前点添加到pos_xy列表中
            调用update()函数在这里相当于调用paintEvent()函数
            每次update()时,之前调用的paintEvent()留下的痕迹都会清空
        '''
        #中间变量pos_tmp提取当前点
        pos_tmp = (event.pos().x(), event.pos().y())
        #pos_tmp添加到self.pos_xy中
        self.pos_xy.append(pos_tmp)

        self.update()

    def mouseReleaseEvent(self, event):
        '''
            重写鼠标按住后松开的事件
            在每次松开后向pos_xy列表中添加一个断点(-1, -1)
            然后在绘画时判断一下是不是断点就行了
            是断点的话就跳过去,不与之前的连续
        '''
        pos_test = (-1, -1)
        self.pos_xy.append(pos_test)

        self.update()

    def btn_recognize_on_clicked(self):
        bbox = (104, 104, 380, 380)
        im = ImageGrab.grab(bbox)    # 截屏,手写数字部分
        im = im.resize((28, 28), Image.ANTIALIAS)  # 将截图转换成 28 * 28 像素

        recognize_result = self.recognize_img(im)  # 调用识别函数

        self.label_result.setText(str(recognize_result))  # 显示识别结果
        self.update()

    def btn_clear_on_clicked(self):
        self.pos_xy = []
        self.label_result.setText('')
        self.update()

    def btn_close_on_clicked(self):
        self.close()

    def recognize_img(self, img):
        myimage = img.convert('L')  # 转换成灰度图
        tv = list(myimage.getdata())  # 获取图片像素值
        tva = [(255 - x) * 1.0 / 255.0 for x in tv]  # 转换像素范围到[0 1], 0是纯白 1是纯黑

        init = tf.global_variables_initializer()
        saver = tf.train.Saver  # 不带括号

        with tf.Session() as sess:
            sess.run(init)
            saver = tf.train.import_meta_graph('minst_cnn_model.ckpt.meta')  # 载入模型结构
            saver.restore(sess, 'minst_cnn_model.ckpt')  # 载入模型参数

            graph = tf.get_default_graph()  # 加载计算图
            x = graph.get_tensor_by_name("x:0")  # 从模型中读取占位符变量
            keep_prob = graph.get_tensor_by_name("keep_prob:0")
            y_conv = graph.get_tensor_by_name("y_conv:0")  # 关键的一句  从模型中读取占位符变量

            prediction = tf.argmax(y_conv, 1)
            predint = prediction.eval(feed_dict={x: [tva], keep_prob: 1.0}, session=sess)  # feed_dict输入数据给placeholder占位符
            print(predint[0])
        return predint[0]

第三步:【制作exe文件】
第一步:
pip install pyinstaller

第二步:
pyinstaller main.py


最后:
pyinstaller -F main.spec 打包成功

备注:
除了程序打包,其他资源(图、模型等要手动添加到exe文件夹)

问题解决:
出现:'str' object has no attribute 'items'
解决:
管理员:pip install -U --pre setuptools

出现:RecursionError: maximum recursion depth exceeded
解决:
在此总结下解决步骤:


1)pyinstaller -F xxx.py 


这一步肯定会报上述错误导致失败,但是会产生一个xxx.spec文件

2)在xxx.spec文件中增加两行(添加在原文件第二行):


import sys

sys.setrecursionlimit(5000)

3)pyinstaller xxx.spec



出现:  Cannot find existing PyQt5 plugin directories 
	Paths checked:
解决:pip install PyQt5

——————————————————————————————————————————————————————————————————————————————————
——————————————————————————————————————————————————————————————————————————————————

Tensorflow(3):创建画板,实时在线手写体识别--终极篇(PyQt5)
文章链接:https://blog.csdn.net/u011389706/article/details/81460820


需要的库: Python3 + Tensorflow + PyQt5 + PIL


文件说明:

MyMnistWindow.py--------GUI类(画板)

main.py-----------------主程序

mnist_cnn_model.ckpt----训练好的手写体模型,识别率可以达到99.2% (模型训练方法参见博客:https://blog.csdn.net/u011389706/article/details/81455750)


 资源文件(整体项目):我的实验结果-PYQT_MNIST系统

 




VGG16_tfrecords_17分类

项目地址(包含图片、训练、测试):pan.baidu.com/s/1q1gtXscbTXhEls1YlTSWtA




随意定义一个卷积网络进行四分类

从我的github项目里面下载:https://github.com/DJdongbudong/Tensorflow-cnn

改正后的项目:https://pan.baidu.com/s/1sK5Hel_ohENz9G1zyeg51A

包含:data-{0,1,2,3}、logs-{checkpoint等训练结果保存}、tfrecords.py、model.py、train.py、eval.py

data-{0,1,2,3}
logs-{checkpoint等训练结果保存}

子函数:
数据读取:tfrecords.py
网络模型:model.py

主函数:
train.py

测试函数:
eval.py

训练:
python train.py
{data的数据生成tfrecords格式、训练train.tfrecords数据、保存到logs}
python eval.py
{加载logs的模型、测试test的数据}

 

 

编译器的操作

经常出现空格和tab的格式问题:

cnn 2分类 

程序比较清晰:

常用参数设置—》输入数据模块—》卷积网络模块—》训练模块

程序位置:

dir/main.py、dir/data/0/**.jpg、dir/data/1/**.jpg

卷积池化:

不足:

没有用tfrecord数据类型,训练受硬盘读取速度影响,之后进行改进。

# coding:utf-8
import os
import numpy as np
import tensorflow as tf

# 变量声明
N_CLASSES = 2  # 分类类别
IMG_W = 28  # resize图像,太大的话训练时间久
IMG_H = 28
BATCH_SIZE = 20  # 每个batch要放多少张图片
CAPACITY = 200  # 一个队列最大多少
MAX_STEP = 10000  # 一般大于10K
learning_rate = 0.0001  # 一般小于0.0001


class inputData:
    # 训练数据及标签
    def get_files(filename):
        class_train = []
        label_train = []
        num_pic = 0
        num_class = 0
        for train_class in os.listdir(filename):
            num_class = num_class + 1
            for file in os.listdir(filename + train_class):
                num_pic = num_pic + 1
                class_train.append(filename + train_class + '/' + file)
                # print (class_train)
                label_train.append(train_class)
                # print (label_train)

            # 打印出提取图片的情况,检测是否正确提取
        print("There are %c class\n" % (train_class), end="")
        print("There are %d files\n" % (num_pic))

        temp = np.array([class_train, label_train])
        temp = temp.transpose()

        # shuffle the samples随机打乱数据
        np.random.shuffle(temp)

        # after transpose, images is in dimension 0 and label in dimension 1
        image_list = list(temp[:, 0])
        label_list = list(temp[:, 1])
        label_list = [int(i) for i in label_list]
        # print(label_list)
        return image_list, label_list

    # 将image和label转为list格式数据,因为后边用到的的一些tensorflow函数接收的是list格式数据
    # 为了方便网络的训练,输入数据进行batch处理
    # image_W, image_H, :图像高度和宽度
    # batch_size:每个batch要放多少张图片
    # capacity:一个队列最大多少
    # 获取批次batch
    def get_batches(image, label, resize_w, resize_h, batch_size, capacity):
        # 转换类型
        image = tf.cast(image, tf.string)
        label = tf.cast(label, tf.int64)
        # tensor生成器 制作 一个输入tensor
        queue = tf.train.slice_input_producer([image, label])
        label = queue[1]
        image_c = tf.read_file(queue[0])

        # step2:将图像解码,使用相同类型的图像
        image = tf.image.decode_jpeg(image_c, channels=3)

        # step3:数据预处理,对图像进行旋转、缩放、裁剪、归一化等操作,让计算出的模型更健壮。
        image = tf.image.resize_image_with_crop_or_pad(image, resize_w, resize_h)
        # (x - mean) / adjusted_stddev对resize后的图片进行标准化处理
        image = tf.image.per_image_standardization(image)

        # step4:生成batch
        image_batch, label_batch = tf.train.batch([image, label],
                                                  batch_size=batch_size,
                                                  num_threads=64,
                                                  capacity=capacity)
        images_batch = tf.cast(image_batch, tf.float32)
        labels_batch = tf.reshape(label_batch, [batch_size])
        # 获取两个batch,两个batch即为传入神经网络的数据
        return images_batch, labels_batch


# 函数申明
def conv2d(x, W):
    # 卷积遍历各方向步数为1,SAME:边缘外自动补0,遍历相乘
    # padding 一般只有两个值
    # 卷积层后输出图像大小为:(W+2P-f)/stride+1并向下取整
    return tf.nn.conv2d(x, W, strides=[1, 1, 1, 1], padding='SAME')


def max_pool_2x2(x, name):
    # 池化卷积结果(conv2d)池化层采用kernel大小为3*3,步数也为2,SAME:周围补0,取最大值。数据量缩小了4倍
    # x 是 CNN 第一步卷积的输出量,其shape必须为[batch, height, weight, channels];
    # ksize 是池化窗口的大小, shape为[batch, height, weight, channels]
    # stride 步长,一般是[1,stride, stride,1]
    # 池化层输出图像的大小为(W-f)/stride+1,向上取整
    return tf.nn.max_pool(x, ksize=[1, 3, 3, 1], strides=[1, 2, 2, 1], padding='SAME', name=name)


def weight_variable(shape, n):
    # tf.truncated_normal(shape, mean, stddev)这个函数产生正态分布,均值和标准差自己设定。
    # shape表示生成张量的维度,mean是均值
    # stddev是标准差,,默认最大为1,最小为-1,均值为0
    initial = tf.truncated_normal(shape, stddev=n, dtype=tf.float32)
    return initial


def bias_variable(shape):
    # 创建一个结构为shape矩阵也可以说是数组shape声明其行列,初始化所有值为0.1
    initial = tf.constant(0.1, shape=shape, dtype=tf.float32)
    return initial


class MODEL:
    def model(images, batch_size, n_classes):
        # 搭建网络
        # 第一层卷积
        # 第一二参数值得卷积核尺寸大小,即patch;第三个参数是通道数;第四个是卷积核个数
        with tf.variable_scope('conv1') as scope:
            # 所谓名字的scope,指当绑定了一个名字到一个对象的时候,该名字在程序文本中的可见范围
            w_conv1 = tf.Variable(weight_variable([3, 3, 3, 64], 1.0), name='weights', dtype=tf.float32)
            b_conv1 = tf.Variable(bias_variable([64]), name='biases', dtype=tf.float32)  # 64个偏置值
            # tf.nn.bias_add 是 tf.add 的一个特例:tf.add(tf.matmul(x, w), b) == tf.matmul(x, w) + b
            # h_conv1 = tf.nn.relu(tf.nn.bias_add(conv2d(images, w_conv1), b_conv1), name=scope.name)
            h_conv1 = tf.nn.relu(conv2d(images, w_conv1) + b_conv1, name='conv1')  # 得到128*128*64(假设原始图像是128*128)
        # 第一层池化
        # 3x3最大池化,步长strides为2,池化后执行lrn()操作,局部响应归一化,增强了模型的泛化能力。
        # tf.nn.lrn(input,depth_radius=None,bias=None,alpha=None,beta=None,name=None)
        with tf.variable_scope('pooling1_lrn') as scope:
            pool1 = max_pool_2x2(h_conv1, 'pooling1')  # 得到64*64*64
            norm1 = tf.nn.lrn(pool1, depth_radius=4, bias=1.0, alpha=0.001 / 9.0, beta=0.75, name='norm1')

        # 第二层卷积
        # 32个3x3的卷积核(16通道),padding=’SAME’,表示padding后卷积的图与原图尺寸一致,激活函数relu()
        with tf.variable_scope('conv2') as scope:
            w_conv2 = tf.Variable(weight_variable([3, 3, 64, 32], 0.1), name='weights', dtype=tf.float32)
            b_conv2 = tf.Variable(bias_variable([32]), name='biases', dtype=tf.float32)  # 32个偏置值
            h_conv2 = tf.nn.relu(conv2d(norm1, w_conv2) + b_conv2, name='conv2')  # 得到64*64*32

        # 第二层池化
        # 3x3最大池化,步长strides为2,池化后执行lrn()操作
        with tf.variable_scope('pooling2_lrn') as scope:
            pool2 = max_pool_2x2(h_conv2, 'pooling2')  # 得到32*32*32
            norm2 = tf.nn.lrn(pool2, depth_radius=4, bias=1.0, alpha=0.001 / 9.0, beta=0.75, name='norm2')

        # 第三层卷积
        # 16个3x3的卷积核(16通道),padding=’SAME’,表示padding后卷积的图与原图尺寸一致,激活函数relu()
        with tf.variable_scope('conv3') as scope:
            w_conv3 = tf.Variable(weight_variable([3, 3, 32, 16], 0.1), name='weights', dtype=tf.float32)
            b_conv3 = tf.Variable(bias_variable([16]), name='biases', dtype=tf.float32)  # 16个偏置值
            h_conv3 = tf.nn.relu(conv2d(norm2, w_conv3) + b_conv3, name='conv3')  # 得到32*32*16

        # 第三层池化
        # 3x3最大池化,步长strides为2,池化后执行lrn()操作
        with tf.variable_scope('pooling3_lrn') as scope:
            pool3 = max_pool_2x2(h_conv3, 'pooling3')  # 得到16*16*16
            norm3 = tf.nn.lrn(pool3, depth_radius=4, bias=1.0, alpha=0.001 / 9.0, beta=0.75, name='norm3')

        # 第四层全连接层
        # 128个神经元,将之前pool层的输出reshape成一行,激活函数relu()
        with tf.variable_scope('local3') as scope:
            reshape = tf.reshape(norm3, shape=[batch_size, -1])
            dim = reshape.get_shape()[1].value
            w_fc1 = tf.Variable(weight_variable([dim, 128], 0.005), name='weights', dtype=tf.float32)
            b_fc1 = tf.Variable(bias_variable([128]), name='biases', dtype=tf.float32)
            h_fc1 = tf.nn.relu(tf.matmul(reshape, w_fc1) + b_fc1, name=scope.name)

        # 第五层全连接层
        # 128个神经元,激活函数relu()
        with tf.variable_scope('local4') as scope:
            w_fc2 = tf.Variable(weight_variable([128, 128], 0.005), name='weights', dtype=tf.float32)
            b_fc2 = tf.Variable(bias_variable([128]), name='biases', dtype=tf.float32)
            h_fc2 = tf.nn.relu(tf.matmul(h_fc1, w_fc2) + b_fc1, name=scope.name)

        # 对卷积结果执行dropout操作
        # keep_prob = tf.placeholder(tf.float32)
        h_fc2_dropout = tf.nn.dropout(h_fc2, 0.5)
        # tf.nn.dropout(x, keep_prob, noise_shape=None, seed=None, name=None)
        # 第二个参数keep_prob: 设置神经元被选中的概率,在初始化时keep_prob是一个占位符

        # Softmax回归层
        # 将前面的FC层输出,做一个线性回归,计算出每一类的得分,在这里是2类,所以这个层输出的是两个得分。
        with tf.variable_scope('softmax_linear') as scope:
            weights = tf.Variable(weight_variable([128, n_classes], 0.005), name='softmax_linear', dtype=tf.float32)
            biases = tf.Variable(bias_variable([n_classes]), name='biases', dtype=tf.float32)
            softmax_linear = tf.add(tf.matmul(h_fc2_dropout, weights), biases, name='softmax_linear')
        # softmax_linear = tf.nn.softmax(tf.add(tf.matmul(h_fc2_dropout, weights), biases, name='softmax_linear'))
        return softmax_linear

    # 最后返回softmax层的输出

    # loss计算
    # 传入参数:logits,网络计算输出值。labels,真实值,在这里是0或者1
    # 返回参数:loss,损失值
    def losses(logits, labels):
        with tf.variable_scope('loss') as scope:
            cross_entropy = tf.nn.sparse_softmax_cross_entropy_with_logits(logits=logits, labels=labels,
                                                                           name='xentropy_per_example')
            loss = tf.reduce_mean(cross_entropy, name='loss')
            tf.summary.scalar(scope.name + '/loss', loss)
        return loss

    # loss损失值优化
    # 输入参数:loss。learning_rate,学习速率。
    # 返回参数:train_op,训练op,这个参数要输入sess.run中让模型去训练。
    def trainning(loss, learning_rate):
        with tf.name_scope('optimizer'):
            optimizer = tf.train.AdamOptimizer(learning_rate=learning_rate)
            global_step = tf.Variable(0, name='global_step', trainable=False)
            train_op = optimizer.minimize(loss, global_step=global_step)
        return train_op

    # 评价/准确率计算
    # 输入参数:logits,网络计算值。labels,标签,也就是真实值,在这里是0或者1。
    # 返回参数:accuracy,当前step的平均准确率,也就是在这些batch中多少张图片被正确分类了。
    def evaluation(logits, labels):
        with tf.variable_scope('accuracy') as scope:
            correct = tf.nn.in_top_k(logits, labels, 1)
            accuracy = tf.reduce_mean(tf.cast(correct, tf.float16))
            tf.summary.scalar(scope.name + '/accuracy', accuracy)
        return accuracy

def RUN():
    train_dir = './data/'  # 训练样本的读入路径data\1、data\2
    logs_train_dir = './logs/'  # logs存储路径
    '''data'''
    print("数据读写中")
    input = inputData
    # 训练数据及标签
    train, train_label = input.get_files(train_dir)
    print(train_label)
    # 获取批次batch
    train_batch, train_label_batch = input.get_batches(train, train_label, IMG_W, IMG_H, BATCH_SIZE, CAPACITY)
    print("train_batch/n")
    print(train_batch)
    # 训练操作定义
    Model = MODEL
    train_logits = Model.model(train_batch, BATCH_SIZE, N_CLASSES)
    train_loss = Model.losses(train_logits, train_label_batch)
    train_op = Model.trainning(train_loss, learning_rate)
    train_acc = Model.evaluation(train_logits, train_label_batch)

    # 这个是log汇总记录
    summary_op = tf.summary.merge_all()

    # 产生一个会话
    sess = tf.Session()
    train_writer = tf.summary.FileWriter(logs_train_dir, sess.graph)

    # 产生一个saver来存储训练好的模型
    saver = tf.train.Saver()

    # 所有节点初始化
    sess.run(tf.global_variables_initializer())

    # 队列监控
    coord = tf.train.Coordinator()  # 设置多线程协调器
    threads = tf.train.start_queue_runners(sess=sess, coord=coord)
    # 进行batch的训练
    try:
        # 执行MAX_STEP步的训练,一步一个batch
        for step in np.arange(MAX_STEP):
            if coord.should_stop():
                break
            # 启动以下操作节点,有个疑问,为什么train_logits在这里没有开启?
            _, tra_loss, tra_acc = sess.run([train_op, train_loss, train_acc])

            # 每隔50步打印一次当前的loss以及acc,同时记录log,写入writer
            if step % 100 == 0:
                print('Step %d, train loss = %.2f, train accuracy = %.2f%%' % (step, tra_loss, tra_acc * 100.0))
                summary_str = sess.run(summary_op)
                train_writer.add_summary(summary_str, step)
            checkpoint_path = os.path.join(logs_train_dir, 'thing.ckpt')
            saver.save(sess, checkpoint_path)
        '''
        # 每隔100步,保存一次训练好的模型
        if (step + 1) == MAX_STEP:
            checkpoint_path = os.path.join(logs_train_dir, 'thing.ckpt')
            saver.save(sess, checkpoint_path, global_step=step)
        '''

    except tf.errors.OutOfRangeError:
        print('Done training -- epoch limit reached')

    finally:
        coord.request_stop()
    coord.join(threads)
    sess.close()

if __name__ == '__main__':
    RUN()

用了区分性比较强的图做试验。

推荐网址:CNN网络架构演进:从LeNet到DenseNet

(keras近代网络实现):https://www.cnblogs.com/skyfsm/p/8451834.html 

卷积神经网络图片识别关键发展 
2012年alexnet:relu激活函数,lrn层,dropdout,重叠最大池化,数据增强 
2014年vggnet:两个3x3卷积代替一个5x5卷积,lrn层用处不大,卷积层越深效果基本越好,1x1卷积核性价比很高 
2014年的Inception net v1:全局平均池化层+维度变换代替最后一个全链接层,多分支小神经网络结构堆叠成大网络,辅助分类节点 
2015年的Inception net v2:学习vggnet两个3x3代替一个5x5,提出batch normalization大幅加速学习 
2015年的Inception net v3:用1*7和7*1代替7*7比vgg的那种方法效果更好 
2015年的ResNet:加入了skip方式,残差学习模块解决了超深神经网络的学习问题 
2016年的Inception net v4:参考了ResNet,加入了skip方式

这此使用tensorflow编码google的Inception net v3,采用tensorflow的slim模块大幅建华设计代码量 
slim模块教程:https://www.2cto.com/kf/201706/649266.html 
完整代码:https://github.com/joliph/tensorflow/blob/master/InceptionV3.py 
我的tensorflow系列代码仓库:https://github.com/joliph/tensorflow/

科普文章 为什么batch normalization效果这么明显:https://www.zhihu.com/question/38102762

用slim简化网络层代码后光网络设计

CNN 多分类

# coding:utf-8
import os
import numpy as np
import tensorflow as tf

# 变量声明
N_CLASSES = 6  # 分类类别
IMG_W = 28  # resize图像,太大的话训练时间久
IMG_H = 28
BATCH_SIZE = 20  # 每个batch要放多少张图片
CAPACITY = 200  # 一个队列最大多少
MAX_STEP = 10000  # 一般大于10K
learning_rate = 0.0001  # 一般小于0.0001


class inputData:
    # 训练数据及标签
    def get_files(filename):
        class_train = []
        label_train = []
        num_pic = 0
        num_class = 0
        for train_class in os.listdir(filename):
            num_class = num_class + 1
            for file in os.listdir(filename + train_class):
                num_pic = num_pic + 1
                class_train.append(filename + train_class + '/' + file)
                # print (class_train)
                label_train.append(train_class)
                # print (label_train)

            # 打印出提取图片的情况,检测是否正确提取
        print("There are %d class\n" % (num_class), end="")
        print("There are %d files\n" % (num_pic))

        temp = np.array([class_train, label_train])
        temp = temp.transpose()

        # shuffle the samples随机打乱数据
        np.random.shuffle(temp)

        # after transpose, images is in dimension 0 and label in dimension 1
        image_list = list(temp[:, 0])
        label_list = list(temp[:, 1])
        label_list = [int(i) for i in label_list]
        # print(label_list)
        return image_list, label_list

    # 将image和label转为list格式数据,因为后边用到的的一些tensorflow函数接收的是list格式数据
    # 为了方便网络的训练,输入数据进行batch处理
    # image_W, image_H, :图像高度和宽度
    # batch_size:每个batch要放多少张图片
    # capacity:一个队列最大多少
    # 获取批次batch
    def get_batches(image, label, resize_w, resize_h, batch_size, capacity):
        # 转换类型
        image = tf.cast(image, tf.string)
        label = tf.cast(label, tf.int64)
        # tensor生成器 制作 一个输入tensor
        queue = tf.train.slice_input_producer([image, label])
        label = queue[1]
        image_c = tf.read_file(queue[0])

        # step2:将图像解码,使用相同类型的图像
        image = tf.image.decode_jpeg(image_c, channels=3)

        # step3:数据预处理,对图像进行旋转、缩放、裁剪、归一化等操作,让计算出的模型更健壮。
        image = tf.image.resize_image_with_crop_or_pad(image, resize_w, resize_h)
        # (x - mean) / adjusted_stddev对resize后的图片进行标准化处理
        image = tf.image.per_image_standardization(image)

        # step4:生成batch
        image_batch, label_batch = tf.train.batch([image, label],
                                                  batch_size=batch_size,
                                                  num_threads=64,
                                                  capacity=capacity)
        images_batch = tf.cast(image_batch, tf.float32)
        labels_batch = tf.reshape(label_batch, [batch_size])
        # 获取两个batch,两个batch即为传入神经网络的数据
        return images_batch, labels_batch


# 函数申明
def conv2d(x, W):
    # 卷积遍历各方向步数为1,SAME:边缘外自动补0,遍历相乘
    # padding 一般只有两个值
    # 卷积层后输出图像大小为:(W+2P-f)/stride+1并向下取整
    return tf.nn.conv2d(x, W, strides=[1, 1, 1, 1], padding='SAME')


def max_pool_2x2(x, name):
    # 池化卷积结果(conv2d)池化层采用kernel大小为3*3,步数也为2,SAME:周围补0,取最大值。数据量缩小了4倍
    # x 是 CNN 第一步卷积的输出量,其shape必须为[batch, height, weight, channels];
    # ksize 是池化窗口的大小, shape为[batch, height, weight, channels]
    # stride 步长,一般是[1,stride, stride,1]
    # 池化层输出图像的大小为(W-f)/stride+1,向上取整
    return tf.nn.max_pool(x, ksize=[1, 3, 3, 1], strides=[1, 2, 2, 1], padding='SAME', name=name)


def weight_variable(shape, n):
    # tf.truncated_normal(shape, mean, stddev)这个函数产生正态分布,均值和标准差自己设定。
    # shape表示生成张量的维度,mean是均值
    # stddev是标准差,,默认最大为1,最小为-1,均值为0
    initial = tf.truncated_normal(shape, stddev=n, dtype=tf.float32)
    return initial


def bias_variable(shape):
    # 创建一个结构为shape矩阵也可以说是数组shape声明其行列,初始化所有值为0.1
    initial = tf.constant(0.1, shape=shape, dtype=tf.float32)
    return initial


class MODEL:
    def model(images, batch_size, n_classes):
        # 搭建网络
        # 第一层卷积
        # 第一二参数值得卷积核尺寸大小,即patch;第三个参数是通道数;第四个是卷积核个数
        with tf.variable_scope('conv1') as scope:
            # 所谓名字的scope,指当绑定了一个名字到一个对象的时候,该名字在程序文本中的可见范围
            w_conv1 = tf.Variable(weight_variable([3, 3, 3, 64], 1.0), name='weights', dtype=tf.float32)
            b_conv1 = tf.Variable(bias_variable([64]), name='biases', dtype=tf.float32)  # 64个偏置值
            # tf.nn.bias_add 是 tf.add 的一个特例:tf.add(tf.matmul(x, w), b) == tf.matmul(x, w) + b
            # h_conv1 = tf.nn.relu(tf.nn.bias_add(conv2d(images, w_conv1), b_conv1), name=scope.name)
            h_conv1 = tf.nn.relu(conv2d(images, w_conv1) + b_conv1, name='conv1')  # 得到128*128*64(假设原始图像是128*128)
        # 第一层池化
        # 3x3最大池化,步长strides为2,池化后执行lrn()操作,局部响应归一化,增强了模型的泛化能力。
        # tf.nn.lrn(input,depth_radius=None,bias=None,alpha=None,beta=None,name=None)
        with tf.variable_scope('pooling1_lrn') as scope:
            pool1 = max_pool_2x2(h_conv1, 'pooling1')  # 得到64*64*64
            norm1 = tf.nn.lrn(pool1, depth_radius=4, bias=1.0, alpha=0.001 / 9.0, beta=0.75, name='norm1')

        # 第二层卷积
        # 32个3x3的卷积核(16通道),padding=’SAME’,表示padding后卷积的图与原图尺寸一致,激活函数relu()
        with tf.variable_scope('conv2') as scope:
            w_conv2 = tf.Variable(weight_variable([3, 3, 64, 32], 0.1), name='weights', dtype=tf.float32)
            b_conv2 = tf.Variable(bias_variable([32]), name='biases', dtype=tf.float32)  # 32个偏置值
            h_conv2 = tf.nn.relu(conv2d(norm1, w_conv2) + b_conv2, name='conv2')  # 得到64*64*32

        # 第二层池化
        # 3x3最大池化,步长strides为2,池化后执行lrn()操作
        with tf.variable_scope('pooling2_lrn') as scope:
            pool2 = max_pool_2x2(h_conv2, 'pooling2')  # 得到32*32*32
            norm2 = tf.nn.lrn(pool2, depth_radius=4, bias=1.0, alpha=0.001 / 9.0, beta=0.75, name='norm2')

        # 第三层卷积
        # 16个3x3的卷积核(16通道),padding=’SAME’,表示padding后卷积的图与原图尺寸一致,激活函数relu()
        with tf.variable_scope('conv3') as scope:
            w_conv3 = tf.Variable(weight_variable([3, 3, 32, 16], 0.1), name='weights', dtype=tf.float32)
            b_conv3 = tf.Variable(bias_variable([16]), name='biases', dtype=tf.float32)  # 16个偏置值
            h_conv3 = tf.nn.relu(conv2d(norm2, w_conv3) + b_conv3, name='conv3')  # 得到32*32*16

        # 第三层池化
        # 3x3最大池化,步长strides为2,池化后执行lrn()操作
        with tf.variable_scope('pooling3_lrn') as scope:
            pool3 = max_pool_2x2(h_conv3, 'pooling3')  # 得到16*16*16
            norm3 = tf.nn.lrn(pool3, depth_radius=4, bias=1.0, alpha=0.001 / 9.0, beta=0.75, name='norm3')

        # 第四层全连接层
        # 128个神经元,将之前pool层的输出reshape成一行,激活函数relu()
        with tf.variable_scope('local3') as scope:
            reshape = tf.reshape(norm3, shape=[batch_size, -1])
            dim = reshape.get_shape()[1].value
            w_fc1 = tf.Variable(weight_variable([dim, 128], 0.005), name='weights', dtype=tf.float32)
            b_fc1 = tf.Variable(bias_variable([128]), name='biases', dtype=tf.float32)
            h_fc1 = tf.nn.relu(tf.matmul(reshape, w_fc1) + b_fc1, name=scope.name)

        # 第五层全连接层
        # 128个神经元,激活函数relu()
        with tf.variable_scope('local4') as scope:
            w_fc2 = tf.Variable(weight_variable([128, 128], 0.005), name='weights', dtype=tf.float32)
            b_fc2 = tf.Variable(bias_variable([128]), name='biases', dtype=tf.float32)
            h_fc2 = tf.nn.relu(tf.matmul(h_fc1, w_fc2) + b_fc1, name=scope.name)

        # 对卷积结果执行dropout操作
        # keep_prob = tf.placeholder(tf.float32)
        h_fc2_dropout = tf.nn.dropout(h_fc2, 0.5)
        # tf.nn.dropout(x, keep_prob, noise_shape=None, seed=None, name=None)
        # 第二个参数keep_prob: 设置神经元被选中的概率,在初始化时keep_prob是一个占位符

        # Softmax回归层
        # 将前面的FC层输出,做一个线性回归,计算出每一类的得分,在这里是2类,所以这个层输出的是两个得分。
        with tf.variable_scope('softmax_linear') as scope:
            weights = tf.Variable(weight_variable([128, n_classes], 0.005), name='softmax_linear', dtype=tf.float32)
            biases = tf.Variable(bias_variable([n_classes]), name='biases', dtype=tf.float32)
            softmax_linear = tf.add(tf.matmul(h_fc2_dropout, weights), biases, name='softmax_linear')
        # softmax_linear = tf.nn.softmax(tf.add(tf.matmul(h_fc2_dropout, weights), biases, name='softmax_linear'))
        return softmax_linear

    # 最后返回softmax层的输出

    # loss计算
    # 传入参数:logits,网络计算输出值。labels,真实值,在这里是0或者1
    # 返回参数:loss,损失值
    def losses(logits, labels):
        with tf.variable_scope('loss') as scope:
            cross_entropy = tf.nn.sparse_softmax_cross_entropy_with_logits(logits=logits, labels=labels,
                                                                           name='xentropy_per_example')
            loss = tf.reduce_mean(cross_entropy, name='loss')
            tf.summary.scalar(scope.name + '/loss', loss)
        return loss

    # loss损失值优化
    # 输入参数:loss。learning_rate,学习速率。
    # 返回参数:train_op,训练op,这个参数要输入sess.run中让模型去训练。
    def trainning(loss, learning_rate):
        with tf.name_scope('optimizer'):
            optimizer = tf.train.AdamOptimizer(learning_rate=learning_rate)
            global_step = tf.Variable(0, name='global_step', trainable=False)
            train_op = optimizer.minimize(loss, global_step=global_step)
        return train_op

    # 评价/准确率计算
    # 输入参数:logits,网络计算值。labels,标签,也就是真实值,在这里是0或者1。
    # 返回参数:accuracy,当前step的平均准确率,也就是在这些batch中多少张图片被正确分类了。
    def evaluation(logits, labels):
        with tf.variable_scope('accuracy') as scope:
            correct = tf.nn.in_top_k(logits, labels, 1)
            accuracy = tf.reduce_mean(tf.cast(correct, tf.float16))
            tf.summary.scalar(scope.name + '/accuracy', accuracy)
        return accuracy

def RUN():
    train_dir = './data/'  # 训练样本的读入路径data\1、data\2
    logs_train_dir = './logs/'  # logs存储路径
    '''data'''
    print("数据读写中")
    input = inputData
    # 训练数据及标签
    train, train_label = input.get_files(train_dir)
    print(train_label)
    # 获取批次batch
    train_batch, train_label_batch = input.get_batches(train, train_label, IMG_W, IMG_H, BATCH_SIZE, CAPACITY)
    print("train_batch/n")
    print(train_batch)
    # 训练操作定义
    Model = MODEL
    train_logits = Model.model(train_batch, BATCH_SIZE, N_CLASSES)
    train_loss = Model.losses(train_logits, train_label_batch)
    train_op = Model.trainning(train_loss, learning_rate)
    train_acc = Model.evaluation(train_logits, train_label_batch)

    # 这个是log汇总记录
    summary_op = tf.summary.merge_all()

    # 产生一个会话
    sess = tf.Session()
    train_writer = tf.summary.FileWriter(logs_train_dir, sess.graph)

    # 产生一个saver来存储训练好的模型
    saver = tf.train.Saver()

    # 所有节点初始化
    sess.run(tf.global_variables_initializer())

    # 队列监控
    coord = tf.train.Coordinator()  # 设置多线程协调器
    threads = tf.train.start_queue_runners(sess=sess, coord=coord)
    # 进行batch的训练
    try:
        # 执行MAX_STEP步的训练,一步一个batch
        for step in np.arange(MAX_STEP):
            if coord.should_stop():
                break
            # 启动以下操作节点,有个疑问,为什么train_logits在这里没有开启?
            _, tra_loss, tra_acc = sess.run([train_op, train_loss, train_acc])

            # 每隔50步打印一次当前的loss以及acc,同时记录log,写入writer
            if step % 100 == 0:
                print('Step %d, train loss = %.2f, train accuracy = %.2f%%' % (step, tra_loss, tra_acc * 100.0))
                summary_str = sess.run(summary_op)
                train_writer.add_summary(summary_str, step)
            checkpoint_path = os.path.join(logs_train_dir, 'thing.ckpt')
            saver.save(sess, checkpoint_path)
        '''
        # 每隔100步,保存一次训练好的模型
        if (step + 1) == MAX_STEP:
            checkpoint_path = os.path.join(logs_train_dir, 'thing.ckpt')
            saver.save(sess, checkpoint_path, global_step=step)
        '''

    except tf.errors.OutOfRangeError:
        print('Done training -- epoch limit reached')

    finally:
        coord.request_stop()
    coord.join(threads)
    sess.close()

if __name__ == '__main__':
    RUN()

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

智能之心

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值