import tensorflow as tf
import os
batch_size = 50
Flages = tf.app.flags.FLAGS
tf.app.flags.DEFINE_integer("is_train",1,"train or test")
class convolutin_picture(object):
def __init__(self,filelist):
self.filelist = filelist
self.label_bytes = 1
self.height = 32
self.width = 32
self.depth = 3
self.image_bytes = self.height * self.width * self.depth
self.record_bytes = self.image_bytes + self.label_bytes
def read_cifar10(self):
#构造文件队列
file_queue = tf.train.string_input_producer(self.filelist)
#设置每次读取二进制文件的长度
reader = tf.FixedLengthRecordReader(record_bytes=self.record_bytes)
#读取文件内容
key,value = reader.read(file_queue)
#解码
record_bytes = tf.decode_raw(value,tf.uint8)
#分割数据并转换数据类型
label = tf.cast(tf.slice(record_bytes,[0],[self.label_bytes]),tf.int32)
image = tf.slice(record_bytes,[self.label_bytes],[self.image_bytes])
#将图片的数据转换成3维数据
image_reshape = tf.cast(tf.reshape(image,[self.height,self.width,self.depth]),tf.float32)
return label,image_reshape
#对图片数据进行增强处理
def enhancd_image(self,batch_size,distorted=None):
#在方法内部调用同一类中的另一个方法
label,image_reshape = convolutin_picture.read_cifar10(self)
if distorted == True:
#将[32,32,3]大小的图片随机裁剪成[24,24,3]
cropped_image = tf.random_crop(image_reshape,[24,24,3])
#随机左右翻转图片
flipped_image = tf.image.random_flip_left_right(cropped_image)
#调整亮度
adjusted_brightness = tf.image.random_brightness(flipped_image,0.8)
#调整对比度
adjusted_contrast = tf.image.random_contrast(adjusted_brightness,lower=0.2,upper=1.8)
#标准化照片
float_image = tf.image.per_image_standardization(adjusted_contrast)
#设置图片数据和label的形状
final_image = tf.reshape(float_image,[24,24,3])
final_label = tf.reshape(label,[1])
#构建一个batch
label_train,image_train = tf.train.batch([final_label,final_image],batch_size= batch_size,num_threads=16,capacity=100)
#返回值,label_train是[batch,1]的数据,转换成[batch]
return tf.reshape(label_train,[batch_size]),image_train
else:
#不需要图片数据加强的
resized_image = tf.image.resize_image_with_crop_or_pad(image_reshape,24,24)
float_image = tf.image.per_image_standardization(resized_image)
final_image = tf.reshape(float_image, [24, 24, 3])
final_label = tf.reshape(label, [1])
label_test, image_test = tf.train.batch([final_label, final_image], batch_size=batch_size,num_threads=16,capacity=100)
return tf.reshape(label_test,[batch_size]),image_test
#构造权重函数,并对权重L2正则化,添加到数据集
def variable_with_weight_loss(self,shape,stddev,w1):
var = tf.Variable(tf.truncated_normal(shape,mean=0.0,stddev=stddev))
if w1 is not None:
weights_loss = tf.multiply(tf.nn.l2_loss(var),w1,name="weights_loss")
tf.add_to_collection("losses",weights_loss)
return var
def train(self):
#构造占位符
x = tf.placeholder(tf.float32, [batch_size, 24, 24, 3], "label")
y = tf.placeholder(tf.int32, [batch_size], "image")
#构造卷积核参数
var1 = convolutin_picture.variable_with_weight_loss(self,[5,5,3,64],0.05,0.0)
#卷积核偏置
bias1 = tf.zeros([64],tf.float32)
#卷积层
conv1_result = tf.nn.conv2d(x,var1,strides=[1,1,1,1],padding="SAME")
#卷积层输出给softmax非线性化,然后给池化层
pool1_input = tf.nn.relu(tf.add(conv1_result,bias1))
pool1_output = tf.nn.max_pool(pool1_input,[1,3,3,1],[1,2,2,1],padding="SAME")
#对二个卷积层和池化层
var2 = convolutin_picture.variable_with_weight_loss(self,[5,5,64,64],0.05,0.0)
bias2 = tf.Variable(tf.constant(0.1))
conv2_result = tf.nn.conv2d(pool1_output,var2,strides=[1,1,1,1],padding="SAME")
pool2_input = tf.nn.relu(tf.add(conv2_result,bias2))
pool2_output = tf.nn.max_pool(pool2_input,[1,3,3,1],[1,2,2,1],padding="SAME")
#将池化层输出的3维数据转换成1维数据,传给全连接层
reshape = tf.reshape(pool2_output,[batch_size,-1])
#3维转化成1后有多少个数据
dim = tf.cast(tf.shape(reshape)[1],"int32")
with tf.Session() as sess:
dim1 = sess.run(dim)
#全连接层1
var3 = convolutin_picture.variable_with_weight_loss(self,[dim1,384],stddev=0.04,w1=0.004)
bias3 = tf.Variable(tf.constant(0.1,shape=[384]))
con1 = tf.nn.relu(tf.matmul(reshape,var3)+bias3)
#全连接层2
var4 = convolutin_picture.variable_with_weight_loss(self,shape=[384,192],stddev=0.04,w1=0.004)
bias4 = tf.Variable(tf.constant(0.1,shape=[192]))
con2 = tf.nn.relu(tf.matmul(con1,var4)+bias4)
#全连接层3
var5 = convolutin_picture.variable_with_weight_loss(self,[192,10],stddev=1/192.0,w1=0.0)
bias5 = tf.Variable(tf.constant(0.0,shape=[10]))
result = tf.add(tf.matmul(con2,var5),bias5)
#交叉熵损失
loss = tf.nn.sparse_softmax_cross_entropy_with_logits(labels=y,logits=result)
#正则化损失
weights_with_l2_loss = tf.add_n(tf.get_collection("losses"))
#总损失
total_loss = tf.reduce_mean(loss)+weights_with_l2_loss
#自适应学习率优化
train_op = tf.train.AdamOptimizer(0.001).minimize(total_loss)
#predictions:预测的结果,预测矩阵大小为样本数(batch)×标注的类(class)的个数的二维矩阵。
#targets:实际的标签,大小为样本数(batch)。
#k:每个样本的预测结果的前k个最大的数里面是否包含targets预测中的标签,一般都是取1,即取predictions中每个batch样本中最大的数的索引与标签对比。
top_k_op = tf.nn.in_top_k(result,y,1)
#获得训练或测试数据,该数据放在for循环里,程序执行不报错,但是没有结果输出。
#所以batch的数据要放在启动线程之前
label_train, image_train = reader.enhancd_image(batch_size, True)
label_test, image_test = reader.enhancd_image(batch_size, False)
initial_variable = tf.global_variables_initializer()
with tf.Session() as sess:
sess.run(initial_variable)
#启动线程
coord = tf.train.Coordinator()
threads = tf.train.start_queue_runners(sess, coord)
for i in range(1000):
if Flages.is_train == True:
real_label, real_image = sess.run([label_train, image_train])
a,b = sess.run([train_op,total_loss],feed_dict={x:real_image,y:real_label})
print("step%d,loss=%.2f"%(i,b))
else:
real_label, real_image = sess.run([label_test, image_test])
a, b = sess.run([train_op,total_loss], feed_dict={x: real_image, y: real_label})
print("step%d,loss=%.2f"%(i,b))
#关闭线程
coord.request_stop()
coord.join(threads)
if __name__ == "__main__":
file_name = os.listdir("/root/cifar/cifar-10-batches-bin")
filelist = [os.path.join("/root/cifar/cifar-10-batches-bin", file) for file in file_name if file[-3:] == "bin"]
reader = convolutin_picture(filelist)
reader.train()
《tensorflow深度学习算法原理与编程实战》第七章代码(自编)
最新推荐文章于 2021-11-25 17:31:36 发布