利用TFRcord文件完成建立AlexNex
数据来源于猫狗大战,我在这里用分好了,如下图所示
文章图片
首先是建立TFRcord文件,如下所示:
import os
import tensorflow as tf
from PIL import Image#注意Image,后面会用到
import matplotlib.pyplot as plt
import numpy as np
cwd='D:\比赛\猫狗大战\cat_vs_dog\\train\\'
classes={'cat','dog'} #人为 设定 2 类
writer= tf.python_io.TFRecordWriter("D:\比赛\猫狗大战\cat_vs_dog\\train\\train.tfrecords") #要生成的文件
for index,name in enumerate(classes):
class_path=cwd+name+'\\'
for img_name in os.listdir(class_path):
img_path=class_path+img_name #每一个图片的地址
img=Image.open(img_path)
img= img.resize((208,208))
img_raw=img.tobytes()#将图片转化为二进制格式
example = tf.train.Example(features=tf.train.Features(feature={
"label": tf.train.Feature(int64_list=tf.train.Int64List(value=https://www.it610.com/article/[index])),'image_raw': tf.train.Feature(bytes_list=tf.train.BytesList(value=https://www.it610.com/article/[img_raw]))
})) #example对象对label和image数据进行封装
writer.write(example.SerializeToString())#序列化为字符串
writer.close()
这样就可以建立tfrecords文件了
文章图片
如何读入文件?如下所示:
def read_and_decode(tfrecords_file, batch_size=5,epoch_num=3):
'''read and decode tfrecord file, generate (image, label) batches
Args:
tfrecords_file:tfrecord 文件地址
batch_size: 每个batch大小,我计算机性能差,设置的比较小
epoch_num:重复多少次
Returns:
image: 4D tensor - [batch_size, width, height, channel]
label: 1D tensor - [batch_size]
'''
# make an input queue from the tfrecord file
filename_queue = tf.train.string_input_producer([tfrecords_file])reader = tf.TFRecordReader()
_, serialized_example = reader.read(filename_queue)img_features = tf.parse_single_example(
serialized_example,
features={
'label': tf.FixedLenFeature([], tf.int64),
'image_raw': tf.FixedLenFeature([], tf.string),
})
image = tf.decode_raw(img_features['image_raw'], tf.uint8)
label = tf.cast(img_features['label'], tf.float32)
##########################################################
# you can put data augmentation here, I didn't use it
##########################################################
# all the images of notMNIST are 28*28, you need to change the image size if you use other dataset.image = tf.reshape(image, [208, 208,3])
#label=tf.reshape(label, [batch_size,2])
#image.set_shape([208*208*3])image_batch, label_batch = tf.train.batch([image, label],
batch_size= batch_size,
num_threads= 64,
capacity = 2000)#image = tf.image.per_image_standardization(image)
#从tensor列表中按顺序或随机抽取一个tensor准备放入文件名称队列
input_queue = tf.train.slice_input_producer([image_batch, label_batch], num_epochs=epoch_num, shuffle=False) image_batch, label_batch = tf.train.batch(input_queue, batch_size, num_threads=2, capacity=10, allow_smaller_final_batch=False)
image_batch=tf.cast(image_batch, tf.float32)
label_batch=tf.cast(label_batch, tf.int32)
return image_batch, tf.reshape(label_batch, [batch_size])
通过以上即可将文件读取数据了,那怎么使用这种tensor呢,我看到很多博客建议的是将tensor变为numpy的格式,再通过feed_dict填补数据,这种方法非常愚蠢,完全没有利用到TFRcord文件的优势。我接下来就利用猫狗大战的数据,写个简单的方法实现AlexNet。
首先是定义网格参数以及基础函数:
#定义网络超参数
learning_rate = 0.0001
train_epochs = 5
batch_size = 5
display = 10
t = 50# 每轮随机抽的次数
# 网络参数
n_input = 208*208
n_classes = 2keep_prob= 0.75
# 卷积层使用截断正太分布初始化,shape为列表对象def conv_weight_init(shape,stddev):
weight = tf.Variable(tf.truncated_normal(dtype=tf.float32, shape=shape, stddev=stddev))
return weight# 全连接层使用xavier初始化
def xavier_init(layer1, layer2, constant = 1):
Min = -constant * np.sqrt(6.0 / (layer1 + layer2))
Max = constant * np.sqrt(6.0 / (layer1 + layer2))
weight = tf.random_uniform((layer1, layer2), minval = Min, maxval = Max, dtype = tf.float32)
return tf.Variable(weight)# 偏置
def biases_init(shape):
biases = tf.Variable(tf.random_normal(shape, dtype=tf.float32))
return biases
#卷积 +池化+LRN
def conv2d(image, weight, stride=1):
return tf.nn.conv2d(image, weight, strides=[1,stride,stride,1],padding='SAME')def max_pool(tensor, k = 2, stride=2):
return tf.nn.max_pool(tensor, ksize=[1,k,k,1], strides=[1,stride,stride,1],padding='SAME')def lrnorm(tensor):
return tf.nn.lrn(tensor,depth_radius=4, bias=1.0, alpha=0.001/9.0, beta=0.75)
# AlexNet中的LRN不知道是否适合
##卷积
def inference(images,batch_size=5):
# 转换image的shape
imgs = tf.reshape(images,[-1, 208, 208, 3])
imgs=tf.cast(imgs, tf.float32)# 初始化权重
# wc = weight convolution
wc1 = conv_weight_init([5, 5, 3, 12], 0.05)
wc2 = conv_weight_init([5, 5, 12, 32], 0.05)
wc3 = conv_weight_init([3, 3, 32, 48], 0.05)
wc4 = conv_weight_init([3, 3, 48, 48], 0.05)
wc5 = conv_weight_init([3, 3, 48, 32], 0.05)
# wf : weight fullconnection
wf1 = xavier_init(26*26*32, 512)
wf2 = xavier_init(512, 512)
wf3 = xavier_init(512, 2)# 初始化偏置
bc1 = biases_init([12])
bc2 = biases_init([32])
bc3 = biases_init([48])
bc4 = biases_init([48])
bc5 = biases_init([32])
# full connection
bf1 = biases_init([512])
bf2 = biases_init([512])
bf3 = biases_init([2])
# 卷积1
c1= conv2d(imgs, wc1)# 未激活
conv1 = tf.nn.relu(c1 + bc1)
lrn1= lrnorm(conv1)
pool1= max_pool(lrn1)
# 卷积2
conv2 = tf.nn.relu(conv2d(pool1, wc2) + bc2)
lrn2= lrnorm(conv2)
pool2 = max_pool(lrn2)
# 卷积3--5,不在进行LRN,会严重影响网络前馈,反馈的速度(效果还不明显)
conv3 = tf.nn.relu(conv2d(pool2, wc3) + bc3)
#pool3 = max_pool(conv3)
# 卷积4
conv4 = tf.nn.relu(conv2d(conv3, wc4) + bc4)
#pool4 = max_pool(conv4)
# 卷积5
conv5 = tf.nn.relu(conv2d(conv4, wc5) + bc5)
pool5 = max_pool(conv5)##?*26*26*32#pool5#全连接
# 转换pool5的shape
reshape_p5 = tf.reshape(pool5, [-1,26*26*32])
fc1 = tf.nn.relu(tf.matmul(reshape_p5, wf1) + bf1)
# 正则化
drop_fc1 = tf.nn.dropout(fc1, keep_prob)
# full connect 2
fc2 = tf.nn.relu(tf.matmul(drop_fc1, wf2) + bf2)
drop_fc2 = tf.nn.dropout(fc2, keep_prob)
# full connect 3 (输出层)未激活
output = tf.matmul(drop_fc2, wf3) + bf3#?,2
y=tf.reshape(output, [-1,2])
return y#损失函数和优化器
def cost(x,y):
pred=inference(x)
#loss=tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits=pred,labels=y))with tf.variable_scope('loss') as scope:
cross_entropy = tf.nn.sparse_softmax_cross_entropy_with_logits\
(logits=pred, labels=y, name='xentropy_per_example')
loss = tf.reduce_mean(cross_entropy, name='loss')
tf.summary.scalar(scope.name+'/loss', loss)return lossdef 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
【利用TFRcord文件完成建立AlexNex】以上基础函数建立完毕,我们读入数据以及运行以上函数
filename="D:\比赛\猫狗大战\cat_vs_dog\\train\\train.tfrecords"
x,y = read_and_decode(filename, batch_size=5)
train_logits = inference(x,batch_size=5)
train_loss = cost(x, y)
train_op = trainning(train_loss, learning_rate)with tf.Session() as sess:# 先执行初始化工作
sess.run(tf.global_variables_initializer())
sess.run(tf.local_variables_initializer())# 开启一个协调器
coord = tf.train.Coordinator()
# 使用start_queue_runners 启动队列填充
threads = tf.train.start_queue_runners(sess, coord)try:
while not coord.should_stop():
print ('******1******')
# 获取每一个batch中batch_size个样本和标签
_, tra_loss = sess.run([train_op, train_loss])
print('train loss = %.2f,' %( tra_loss))
#image_batch_v, label_batch_v = sess.run([image_batch, label_batch])
#print(image_batch_v.shape, label_batch_v)
except tf.errors.OutOfRangeError:#如果读取到文件队列末尾会抛出此异常
print("done! now lets kill all the threads……")finally:
# 协调器coord发出所有线程终止信号
coord.request_stop()
print('all threads are asked to stop!')
#coord.join(threads) #把开启的线程加入主线程,等待threads结束
print('all threads are stopped!')
运行结果如下所示:
文章图片
推荐阅读
- django-前后端交互
- 如何在Mac中的文件选择框中打开系统隐藏文件夹
- 使用composer自动加载类文件
- ssh生成公钥秘钥
- Android系统启动之init.rc文件解析过程
- Spring|Spring Boot 自动配置的原理、核心注解以及利用自动配置实现了自定义 Starter 组件
- 微信小程序基础知识
- 【万伽复利】什么是复利(如何利用复利赚钱?)
- 误删/清空.bashrc文件/内容
- JavaScript|vue 基于axios封装request接口请求——request.js文件