//之前的代码有问题,重发一遍
这里做个整理,打算给一个ResNet的完整代码实现
这篇博客不对ResNet DenseNet思路做详解,只是提供一个大致的代码实现和编写思路
以及一些自己的小实验
当然也包括ResNeXt和SENet
其中SE-ResNeXt是最后一届ImageNet比赛的冠军模型
当然可能我写得烂……参数没精调…准确率提升也不是很明显
首先是数据处理部分,我自己实现过几个框架
多线程数据读入和处理框架(tf.data)
较早版本的队列多线程读入处理框架
最普通的单线程(用法和自带MNIST一样)读取数据
我用了多线程tf.data
Cifar10原生数据集是python打包的
至于图片的话,参考我的这篇,把Cifar10图片提取出来
主要是为了制成TFRecord格式,这样数据读取速度会很快(毕竟自家的东西优化得给足)
VGG AlexNet之前已经跑过了就不跑了,滑动平均下准确率已经在85%以上了
我自己的AlexNet和VGG16
(均嵌入SENet,并且移除全连接层,当然甚至可以把池化也扔掉,用步长2x2的卷积代替池化,这样的话网络看起来像是全卷积网络FCN)
我用全局平均池化+1x1卷积代替全连接层,同时还加上了BN,SENet等后来才有的结构
准确率能跑到85%以上
比较深的网络(VGG19)不加上BN很难收敛,我跑Kaggle的时候跑了10个epoch还是50%的准确率
戳我了解SENet
戳我了解ResNeXt

SENet感觉像是一种Attention机制
ResNet和ResNeXt的差别不是很大,就是卷积分成了几个通路,像Inception那样
不同的是每个通路都是同构的


有三种等价的实现,我这里采用了c的结构
学习率使用warmup策略,因而学习率可以设置到一个比较大的数字(ResNet50设置到了0.036都基本可以正常训练,不过有一定概率中期崩掉)
网络中的一些超参数:
Optimizer: MomentumOptimizer(SGDM)
conv_initializer:xavier(tf.layers.conv2d默认kernel_initializer,实测比stddev=0.01的截断正态分布好)
momentum:0.9
warmup_step:batch_num*10
learning_rate_base:0.012
learning_rate_decay:0.96
learning_rate_step:batch_num
train_epochs:140
batch_size:128
batch_num:50000/batch_size
SE_rate:32
cardinality:8
regularizer_rate:0.008
drop_rate:0.3
exponential_moving_average_decay:0.999
虽然cifar10只有32x32
但是实际输入网络的时候被resize为64x64 或者128x128 (测试准确率差异在1%以内,可以忽略不记)
完整代码:
ResNet50/ResNeXt/SE-AlexNet
数据处理部分:

import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt
from time import time
from PIL import Image
from sklearn.utils import shuffle
from tqdm import tqdm_notebook as tqdm
import os
from tqdm import tqdm_notebook as tqdm
data_path="C:\\Users\\Shijunfeng\\tensorflow_gpu\\dataseats\\cifar10\\Image"
mode_path="C:\\Users\\Shijunfeng\\tensorflow_gpu\\dataseats\\cifar10\\Image\\TFMode"
tf.reset_default_graph()
def imshows(classes,images,labels,index,amount,predictions=None):#classes 类别数组#image 图片数组#labels 标签数组#index amount 从数组第index开始输出amount张照片#prediction 预测结果fig=plt.gcf()fig.set_size_inches(10,20)#大小看怎么调整合适把for i in range(amount):title="lab:"+classes[np.argmax(labels[index+i])]if predictions is not None:title=title+"prd:"+name[np.argmax(predictions[index+i])]ax=plt.subplot(5,6,i+1)#每行五个,输出6行ax.set_title(title)ax.imshow(images[index+i])plt.show()
class DatasetReader(object):def __init__(self,data_path,image_size=None):self.data_path=data_pathself.img_size=image_sizeself.img_size.append(3)self.train_path=os.path.join(data_path,"train")self.test_path=os.path.join(data_path,"test")self.TF_path=os.path.join(data_path,"TFRecordData")self.tf_train_path=os.path.join(self.TF_path,"train")self.tf_test_path=os.path.join(self.TF_path,"test")self.classes=os.listdir(self.train_path)self.__Makedirs()self.train_batch_initializer=Noneself.test_batch_initializer=Noneself.__CreateTFRecord(self.train_path,self.tf_train_path)self.__CreateTFRecord(self.test_path,self.tf_test_path)def __CreateTFRecord(self,read_path,save_path):path=os.path.join(save_path,"data.TFRecord")if os.path.exists(path):print("find file "+(os.path.join(save_path,"data.TFRecords")))returnelse:print("cannot find file %s,ready to recreate"%(os.path.join(save_path,"data.TFRecords")))writer=tf.python_io.TFRecordWriter(path=path)image_path=[]image_label=[]image_size=[int(self.img_size[0]*1.3),int(self.img_size[1]*1.3)]for label,class_name in enumerate(self.classes):class_path=os.path.join(read_path,class_name)for image_name in os.listdir(class_path):image_path.append(os.path.join(class_path,image_name))image_label.append(label)for i in range(5):image_path,image_label=shuffle(image_path,image_label)for i in tqdm(range(len(image_path)),desc="TFRecord"):image,label=Image.open(image_path[i]).resize(image_size,Image.ANTIALIAS),image_label[i]image=image.convert("RGB")image=image.tobytes()example=tf.train.Example(features=tf.train.Features(feature={"label":tf.train.Feature(int64_list=tf.train.Int64List(value=[label])),"image":tf.train.Feature(bytes_list=tf.train.BytesList(value=[image]))}))writer.write(example.SerializeToString())writer.close()def __Makedirs(self):if not os.path.exists(self.TF_path):os.makedirs(self.TF_path)if not os.path.exists(self.tf_train_path):os.makedirs(self.tf_train_path)if not os.path.exists(self.tf_test_path):os.makedirs(self.tf_test_path)def __parsed(self,tensor):raw_image_size=[int(self.img_size[0]*1.3),int(self.img_size[1]*1.3),3]feature=tf.parse_single_example(tensor,features={"image":tf.FixedLenFeature([],tf.string),"label":tf.FixedLenFeature([],tf.int64)})image=tf.decode_raw(feature["image"],tf.uint8)image=tf.reshape(image,raw_image_size)image=tf.random_crop(image,self.img_size)image=tf.image.per_image_standardization(image)label=tf.cast(feature["label"],tf.int32)label=tf.one_hot(label,len(self.classes))return image,labeldef __parsed_distorted(self,tensor):raw_image_size=[int(self.img_size[0]*1.3),int(self.img_size[1]*1.3),3]feature=tf.parse_single_example(tensor,features={"image":tf.FixedLenFeature([],tf.string),"label":tf.FixedLenFeature([],tf.int64)})image=tf.decode_raw(feature["image"],tf.uint8)image=tf.reshape(image,raw_image_size)image=tf.random_crop(image,self.img_size)image=tf.image.random_flip_left_right(image)image=tf.image.random_flip_up_down(image)image=tf.image.random_brightness(image,max_delta=0.4)image=tf.image.random_hue(image,max_delta=0.4)image=tf.image.random_contrast(image,lower=0.7,upper=1.4)image=tf.image.random_saturation(image,lower=0.7,upper=1.4)image=tf.image.per_image_standardization(image)label=tf.cast(feature["label"],tf.int32)label=tf.one_hot(label,len(self.classes))return image,labeldef __GetBatchIterator(self,path,parsed,batch_size):filename=[os.path.join(path,name)for name in os.listdir(path)]dataset=tf.data.TFRecordDataset(filename)dataset=dataset.prefetch(tf.contrib.data.AUTOTUNE)dataset=dataset.apply(tf.data.experimental.shuffle_and_repeat(buffer_size=10000,count=None,seed=99997))dataset=dataset.apply(tf.data.experimental.map_and_batch(parsed,batch_size))dataset=dataset.apply(tf.data.experimental.prefetch_to_device("/gpu:0"))iterator=dataset.make_initializable_iterator()return iterator.initializer,iterator.get_next()def __detail(self,path):Max=-1e9Min=1e9print("train dataset:")path=[os.path.join(path,name)for name in self.classes]for i in range(len(self.classes)):num=len(os.listdir(path[i]))print("%-12s:%3d"%(self.classes[i],num))Max=max(Max,num)Min=min(Min,num)print("max:%d min:%d"%(Max,Min))def detail(self):print("class num:",len(self.classes))self.__detail(self.train_path)self.__detail(self.test_path)def global_variables_initializer(self):initializer=[]initializer.append(self.train_batch_initializer)initializer.append(self.test_batch_initializer)initializer.append(tf.global_variables_initializer())return initializerdef test_batch(self,batch_size):self.test_batch_initializer,batch=self.__GetBatchIterator(self.tf_test_path,self.__parsed,batch_size)return batchdef train_batch(self,batch_size):self.train_batch_initializer,batch=self.__GetBatchIterator(self.tf_train_path,self.__parsed_distorted,batch_size)return batch

网络结构定义:

#tf.reset_default_graph()
def warmup_exponential_decay(warmup_step,rate_base,global_step,decay_step,decay_rate,staircase=False):linear_increase=rate_base*tf.cast(global_step/warmup_step,tf.float32)exponential_decay=tf.train.exponential_decay(rate_base,global_step-warmup_step,decay_step,decay_rate,staircase)return tf.cond(global_step<=warmup_step,lambda:linear_increase,lambda:exponential_decay)class ConvNet(object):def __init__(self,training=False,regularizer_rate=0.0,drop_rate=0.0,SE_rate=32,cardinality=8,average_class=None):self.training=trainingself.SE_rate=SE_rateself.cardinality=cardinalityself.drop_rate=drop_rateif regularizer_rate!=0.0:self.regularizer=tf.contrib.layers.l2_regularizer(regularizer_rate)else:self.regularizer=Noneif average_class is not None:self.ema=average_class.averageelse:self.ema=Nonedef Xavier(self):tf.contrib.layers.xavier_initializer_conv2d()def BatchNorm(self,x,name="BatchNorm"):return tf.layers.batch_normalization(x,training=self.training,reuse=tf.AUTO_REUSE)def Dropout(self,x):return tf.layers.dropout(x,rate=self.drop_rate,training=self.training)def Conv2d(self,x,filters,ksize,strides=[1,1],padding="SAME",activation=tf.nn.relu,use_bn=True,dilation=[1,1],name="conv"):#Conv BN Reluwith tf.variable_scope(name,reuse=tf.AUTO_REUSE):input_channel=x.shape.as_list()[-1]kernel=tf.get_variable("kernel",ksize+[input_channel,filters],initializer=self.Xavier())bias=tf.get_variable("bias",[filters],initializer=tf.constant_initializer(0.0))if self.ema is not None and self.training==False: #滑动平均kernel,bias=self.ema(kernel),self.ema(bias)conv=tf.nn.conv2d(x,kernel,strides=[1]+strides+[1],padding=padding,dilations=[1]+dilation+[1],name=name)bias_add=tf.nn.bias_add(conv,bias)if use_bn:bias_add=self.BatchNorm(bias_add) #BNif activation is not None:bias_add=activation(bias_add) #Reluif self.regularizer is not None:tf.add_to_collection("losses",self.regularizer(kernel))return bias_adddef CardConv2d(self,x,filters,ksize,strides=[1,1],padding="SAME",activation=tf.nn.relu,use_bn=True,dilation=[1,1],name="cardconv"):'''ResNeXt的多路卷积层'''with tf.variable_scope(name,tf.AUTO_REUSE):split=tf.split(x,num_or_size_splits=self.cardinality,axis=-1)filters=int(filters/self.cardinality)for i in range(len(split)):split[i]=self.Conv2d(x,filters,ksize,strides,padding,activation,use_bn,dilation,name)merge=tf.concat(split,axis=-1)return mergedef MaxPool(self,x,ksize,strides=[1,1],padding="SAME",name="max_pool"):input_channel=x.shape.as_list()[-1]return tf.nn.max_pool(x,ksize=[1]+ksize+[1],strides=[1]+strides+[1],padding=padding,name=name)def GlobalAvgPool(self,x,name="GAP"):ksize=[1]+x.shape.as_list()[1:-1]+[1]return tf.nn.avg_pool(x,ksize=ksize,strides=[1,1,1,1],padding="VALID",name=name)def FC_conv(self,x,dim,activation=tf.nn.relu,use_bn=True,name="conv_1x1"):'''1x1卷积代替全连接层'''return self.Conv2d(x,dim,[1,1],activation=activation,use_bn=use_bn,name=name)def SENet(self,x,name="SENet"):with tf.variable_scope(name,tf.AUTO_REUSE):channel=x.shape.as_list()[-1]squeeze=self.GlobalAvgPool(x,name="squeeze")excitation=self.FC_conv(x,int(channel/self.SE_rate),name="excitation_1")excitation=self.FC_conv(excitation,channel,activation=tf.nn.sigmoid,name="excitation_2")return excitation*xdef Residual(self,x,channels,name="Residual"):with tf.variable_scope(name,tf.AUTO_REUSE):res=self.Conv2d(x,channels[0],[1,1],name="conv_1")res=self.Conv2d(res,channels[1],[3,3],name="conv_2")res=self.Conv2d(res,channels[2],[1,1],activation=None,use_bn=True,name="conv_3")res=self.SENet(res)if x.shape.as_list()[-1]!=channels[2]:x=self.Conv2d(x,channels[2],[1,1],activation=None,use_bn=False,name="conv_linear")return tf.nn.relu(res+x)def ResidualX(self,x,channels,name="Residual"):with tf.variable_scope(name,tf.AUTO_REUSE):res=self.Conv2d(x,channels[0],[1,1],name="conv_1")res=self.CardConv2d(res,channels[1],[3,3],name="conv_2")res=self.Conv2d(res,channels[2],[1,1],activation=None,use_bn=True,name="conv_3")res=self.SENet(res)if x.shape.as_list()[-1]!=channels[2]:x=self.Conv2d(x,channels[2],[1,1],activation=None,use_bn=False,name="conv_linear")return tf.nn.relu(res+x)def ResNet(self,x):x=self.Conv2d(x,64,[7,7],[2,2],name="conv1")x=self.MaxPool(x,[3,3],[2,2],name="pool1")x=self.Residual(x,[64,64,128],name="Residual1_1")x=self.Residual(x,[64,64,128],name="Residual1_2")x=self.Residual(x,[64,64,128],name="Residual1_3")x=self.MaxPool(x,[3,3],[2,2],name="pool2")x=self.Residual(x,[128,128,256],name="Residual2_1")x=self.Residual(x,[128,128,256],name="Residual2_2")x=self.Residual(x,[128,128,256],name="Residual2_3")x=self.Residual(x,[128,128,256],name="Residual2_4")x=self.MaxPool(x,[3,3],[2,2],name="pool2")x=self.Residual(x,[256,256,512],name="Residual3_1")x=self.Residual(x,[256,256,512],name="Residual3_2")x=self.Residual(x,[256,256,512],name="Residual3_3")x=self.Residual(x,[256,256,512],name="Residual3_4")x=self.Residual(x,[256,256,512],name="Residual3_5")x=self.Residual(x,[256,256,512],name="Residual3_6")x=self.MaxPool(x,[3,3],[2,2],name="pool3")x=self.Residual(x,[512,512,1024],name="Residual4_1")x=self.Residual(x,[512,512,1024],name="Residual4_2")x=self.Residual(x,[512,512,1024],name="Residual4_3")x=self.Residual(x,[512,512,1024],name="Residual4_4")x=self.MaxPool(x,[3,3],[2,2],name="pool3")x=self.GlobalAvgPool(x,name="GAP")x=self.Dropout(x)x=self.FC_conv(x,512,name="FC1")x=self.Dropout(x)x=self.FC_conv(x,10,activation=None,use_bn=False,name="FC2")return tf.reshape(x,[-1,10])def ResNeXt(self,x):x=self.Conv2d(x,64,[7,7],[2,2],name="conv1")x=self.MaxPool(x,[3,3],[2,2],name="pool1")x=self.ResidualX(x,[64,64,128],name="Residual1_1")x=self.ResidualX(x,[64,64,128],name="Residual1_2")x=self.ResidualX(x,[64,64,128],name="Residual1_3")x=self.MaxPool(x,[3,3],[2,2],name="pool2")x=self.ResidualX(x,[128,128,256],name="Residual2_1")x=self.ResidualX(x,[128,128,256],name="Residual2_2")x=self.ResidualX(x,[128,128,256],name="Residual2_3")x=self.ResidualX(x,[128,128,256],name="Residual2_4")x=self.MaxPool(x,[3,3],[2,2],name="pool2")x=self.ResidualX(x,[256,256,512],name="Residual3_1")x=self.ResidualX(x,[256,256,512],name="Residual3_2")x=self.ResidualX(x,[256,256,512],name="Residual3_3")x=self.ResidualX(x,[256,256,512],name="Residual3_4")x=self.ResidualX(x,[256,256,512],name="Residual3_5")x=self.ResidualX(x,[256,256,512],name="Residual3_6")x=self.MaxPool(x,[3,3],[2,2],name="pool3")x=self.ResidualX(x,[512,512,1024],name="Residual4_1")x=self.ResidualX(x,[512,512,1024],name="Residual4_2")x=self.ResidualX(x,[512,512,1024],name="Residual4_3")x=self.ResidualX(x,[512,512,1024],name="Residual4_4")x=self.MaxPool(x,[3,3],[2,2],name="pool3")x=self.GlobalAvgPool(x,name="GAP")x=self.Dropout(x)x=self.FC_conv(x,512,name="FC1")x=self.Dropout(x)x=self.FC_conv(x,10,activation=None,use_bn=False,name="FC2")return tf.reshape(x,[-1,10])def VGG19(self,x):x=self.Conv2d(x,64,[3,3],[1,1],name="conv1_1")x=self.Conv2d(x,64,[3,3],[1,1],name="conv1_2")x=self.Maxpool2d(x,[3,3],[2,2],name="pool1")x=self.SENet(x,name="SE_1")x=self.Conv2d(x,128,[3,3],[1,1],name="conv2_1")x=self.Conv2d(x,128,[3,3],[1,1],name="conv2_2")x=self.Maxpool2d(x,[3,3],[2,2],name="pool2")x=self.SENet(x,name="SE_2")x=self.Conv2d(x,256,[3,3],[1,1],name="conv3_1")x=self.Conv2d(x,256,[3,3],[1,1],name="conv3_2")x=self.Conv2d(x,256,[3,3],[1,1],name="conv3_3")x=self.Conv2d(x,256,[3,3],[1,1],name="conv3_4")x=self.Maxpool2d(x,[3,3],[2,2],name="pool3")x=self.SENet(x,name="SE_3")x=self.Conv2d(x,256,[3,3],[1,1],name="conv4_1")x=self.Conv2d(x,256,[3,3],[1,1],name="conv4_2")x=self.Conv2d(x,256,[3,3],[1,1],name="conv4_3")x=self.Conv2d(x,256,[3,3],[1,1],name="conv4_4")x=self.Maxpool2d(x,[3,3],[2,2],name="pool4")x=self.SENet(x,name="SE_4")x=self.Conv2d(x,512,[3,3],[1,1],name="conv5_1")x=self.Conv2d(x,512,[3,3],[1,1],name="conv5_2")x=self.Conv2d(x,512,[3,3],[1,1],name="conv5_3")x=self.Conv2d(x,512,[3,3],[1,1],name="conv5_4")x=self.Maxpool2d(x,[3,3],[2,2],name="pool5")x=self.GlobalAveragPool(x,name="GAP")x=self.FC_conv(x,128,name="FC_1")x=self.Dropout(x)x=self.FC_conv(x,10,activation=None,bn=False,name="FC_2")return tf.reshape(x,[-1,10])def AlexNet(self,x):x=self.Conv2d(x,96,[11,11],[4,4],padding="valid",name="conv_1")x=self.Maxpool2d(x,[3,3],[2,2],padding="valid",name="pool_1")x=self.SENet(x,name="SE_1")x=self.Conv2d(x,256,[5,5],[2,2],name="conv_2")x=self.Maxpool2d(x,[3,3],[2,2],name="pool_2")x=self.SENet(x,name="SE_2")x=self.Conv2d(x,512,[3,3],[1,1],name="conv_3")x=self.SENet(x,name="SE_3")x=self.Conv2d(x,384,[3,3],[1,1],name="conv_4")x=self.SENet(x,name="SE_4")x=self.Conv2d(x,256,[3,3],[1,1],name="conv_5")x=self.Maxpool2d(x,[3,3],[2,2],name="pool_3")x=self.SENet(x,name="SE_5")x=self.GlobalAveragPool(x,name="GAP")x=self.SENet(x,name="SE_6")x=self.FC_conv(x,512,name="FC_1")x=self.Dropout(x)x=self.FC_conv(x,512,name="FC_2")x=self.Dropout(x)x=self.FC_conv(x,10,activation=None,bn=False,name="FC_3")return tf.reshape(x,[-1,10])
x=tf.placeholder(tf.float32,[None,128,128,3])
y=tf.placeholder(tf.float32,[None,10])
is_training=tf.placeholder(tf.bool)
global_step=tf.Variable(0,trainable=False)
train_epochs=160
batch_size=64
batch_num=int(50000/batch_size)
SE_rate=32
cardinality=8
regularizer_rate=0.01
drop_rate=0.5
#数据输入
data=DatasetReader(data_path,[128,128])
train_batch=data.train_batch(batch_size=batch_size)
test_batch=data.test_batch(batch_size=256)
#学习率
warmup_step=batch_num*3
learning_rate_base=0.003
learning_rate_decay=0.97
learning_rate_step=batch_num
learning_rate=exponential_decay_with_warmup(warmup_step,learning_rate_base,global_step,learning_rate_step,learning_rate_decay)
#前向预测
forward=ConvNet(training=is_training,regularizer_rate=regularizer_rate,drop_rate=drop_rate,SE_rate=SE_rate,cardinality=cardinality).ResNeXt(x)
#滑动平均&预测
ema_decay=0.999
ema=tf.train.ExponentialMovingAverage(ema_decay,global_step)
ema_op=ema.apply(tf.trainable_variables())
ema_forward=ConvNet(SE_rate=SE_rate,cardinality=cardinality).ResNeXt(x)
prediction=tf.nn.softmax(ema_forward)
correct_pred=tf.equal(tf.argmax(prediction,1),tf.argmax(y,1))
accuracy=tf.reduce_mean(tf.cast(correct_pred,tf.float32))
#优化器
momentum=0.9
update_ops=tf.get_collection(tf.GraphKeys.UPDATE_OPS)
cross_entropy=tf.losses.softmax_cross_entropy(onehot_labels=y,logits=forward,label_smoothing=0.1)
l2_regularizer_loss=tf.add_n(tf.get_collection("losses"))#l2正则化损失
loss_function=cross_entropy+l2_regularizer_loss
update_ops=tf.get_collection(tf.GraphKeys.UPDATE_OPS)
with tf.control_dependencies(update_ops):optimizer=tf.train.MomentumOptimizer(learning_rate,momentum).minimize(loss_function,global_step=global_step)
#模型保存地址
if not os.path.exists(mode_path):os.makedirs(mode_path)
saver=tf.train.Saver(tf.global_variables())

网络训练:

gpu_options = tf.GPUOptions(allow_growth=True)
loss_list,acc_list=[5.0],[0.0]
step,decay,acc,loss=0,0,0,0
maxacc,minloss=0.5,1e5
with tf.Session(config=tf.ConfigProto(gpu_options=gpu_options)) as sess:print("train start")sess.run(data.global_variables_initializer())for epoch in range(train_epochs):bar=tqdm(range(batch_num),unit=" step",desc="epoch %d:"%(epoch+1))bar.set_postfix({"acc:":acc,"loss:":loss})for batch in bar:images,labels=sess.run(train_batch)sess.run(optimizer,feed_dict={x:images,y:labels,is_training:True})step+=1if step%50==0:decay=min(0.9,(step/50+1)/(step/50+10))images,labels=sess.run(test_batch)acc,loss=sess.run([accuracy,loss_function],feed_dict={x:images,y:labels,is_training:False})acc_list.append(decay*acc_list[-1]+(1-decay)*acc)loss_list.append(decay*loss_list[-1]+(1-decay)*loss)bar.set_postfix({"acc:":acc,"loss:":loss})print("update model with acc:%.3f%%"%(acc_list[-1]*100))  #pred=sess.run(prediction,feed_dict={x:images,is_training:False})#print(pred)

可视化损失和准确率变化曲线

plt.plot(acc_list)
plt.legend(["ResNet"],loc="lower right")
plt.show()
plt.plot(loss_list)
plt.legend(["ResNet"],loc="upper right")
np.save("ResNet_acc.npy",acc_list)
np.save("ResNet_loss.npy",loss_list)

用模型来进行预测:

#raw_image std_image是本地图片,std_image输入网络,raw_image为原图片
image_path="C:\\Users\\Shijunfeng\\tensorflow_gpu\\dataseats\\kaggle\\Img"
image_list=[os.path.join(image_path,name)for name in os.listdir(image_path)]
def imshows(classes,images,labels,index,amount,predictions=None):#显示图片和对应标签fig=plt.gcf()fig.set_size_inches(10,50)#大小看怎么调整合适把for i in range(amount):title="lab:"+classes[np.argmax(labels[index+i])]if predictions is not None:title=title+"prd:"+name[np.argmax(predictions[index+i])]ax=plt.subplot(15,2,i+1)#每行五个,输出6行ax.set_title(title)ax.set_xticks([])ax.set_yticks([])ax.imshow(images[index+i])plt.show()
def decode(image):image=Image.open(image)image=tf.image.resize_images(image,[128,128],method=2)image=tf.image.per_image_standardization(image)return image
raw_images=[Image.open(image)for image in image_list]
std_images=[decode(image)for image in image_list]
gpu_options = tf.GPUOptions(allow_growth=True)
with tf.Session(config=tf.ConfigProto(gpu_options=gpu_options)) as sess: #加载模型,这里网络定义部分同样需要sess.run(data.global_variables_initializer())ckp_state=tf.train.get_checkpoint_state(mode_path)if ckp_state and ckp_state.model_checkpoint_path:saver.restore(sess,ckp_state.model_checkpoint_path)images=sess.run(std_image)labels=sess.run(prediction,feed_dict={x:images,is_training:False})imshows(data.classes,images,labels,0,10) #输出前10张照片以及对应标签

最终测试结果:


在测试集上准确率接近100%(后面过拟合了,目前位置没有解决过拟合问题)
在训练集上能达到90%以上的准确率
总共训练耗时81分钟左右
ResNet101
疯狂堆残差快

  def ResNet(self,x):x=self.Conv2d(x,64,[7,7],[2,2],name="conv1")x=self.MaxPool(x,[3,3],[2,2],name="pool1")x=self.Residual(x,[64,64,256],name="Residual1_1")x=self.Residual(x,[64,64,256],name="Residual1_2")x=self.Residual(x,[64,64,256],name="Residual1_3")x=self.MaxPool(x,[3,3],[2,2],name="pool2")x=self.Residual(x,[128,128,512],name="Residual2_1")x=self.Residual(x,[128,128,512],name="Residual2_2")x=self.Residual(x,[128,128,512],name="Residual2_3")x=self.Residual(x,[128,128,512],name="Residual2_4")x=self.MaxPool(x,[3,3],[2,2],name="pool3")x=self.Residual(x,[256,256,1024],name="Residual3_1")x=self.Residual(x,[256,256,1024],name="Residual3_2")x=self.Residual(x,[256,256,1024],name="Residual3_3")x=self.Residual(x,[256,256,1024],name="Residual3_4")x=self.Residual(x,[256,256,1024],name="Residual3_5")x=self.Residual(x,[256,256,1024],name="Residual3_6")x=self.Residual(x,[256,256,1024],name="Residual3_7")x=self.Residual(x,[256,256,1024],name="Residual3_8")x=self.Residual(x,[256,256,1024],name="Residual3_9")x=self.Residual(x,[256,256,1024],name="Residual3_10")x=self.Residual(x,[256,256,1024],name="Residual3_11")x=self.Residual(x,[256,256,1024],name="Residual3_12")x=self.Residual(x,[256,256,1024],name="Residual3_13")x=self.Residual(x,[256,256,1024],name="Residual3_14")x=self.Residual(x,[256,256,1024],name="Residual3_15")x=self.Residual(x,[256,256,1024],name="Residual3_16")x=self.Residual(x,[256,256,1024],name="Residual3_17")x=self.Residual(x,[256,256,1024],name="Residual3_18")x=self.Residual(x,[256,256,1024],name="Residual3_19")x=self.Residual(x,[256,256,1024],name="Residual3_20")x=self.Residual(x,[256,256,1024],name="Residual3_21")x=self.Residual(x,[256,256,1024],name="Residual3_22")x=self.Residual(x,[256,256,1024],name="Residual3_23")x=self.MaxPool(x,[3,3],[2,2],name="pool4")x=self.Residual(x,[512,512,2048],name="Residual4_1")x=self.Residual(x,[512,512,2048],name="Residual4_2")x=self.Residual(x,[512,512,2048],name="Residual4_3")x=self.Residual(x,[512,512,2048],name="Residual4_4")x=self.MaxPool(x,[3,3],[2,2],name="pool5")x=self.GlobalAvgPool(x,name="GAP")x=self.Dropout(x)x=self.FC_conv(x,784,name="FC1")x=self.Dropout(x)x=self.FC_conv(x,10,activation=None,use_bn=False,name="output")return tf.reshape(x,[-1,10])


可以看到网络测试集准确率能够稳定在90%以上
最后20个epoch求平均值得到准确率为90.945%(91%)
最高准确率为94%(batch_size=256)
SE-ResNet101
残差块后面加上SENet子结构即可

    def Residual(self,x,channels,name="Residual"):with tf.variable_scope(name,tf.AUTO_REUSE):res=self.Conv2d(x,channels[0],[1,1],name="conv_1")res=self.Conv2d(res,channels[1],[3,3],name="conv_2")res=self.Conv2d(res,channels[2],[1,1],activation=None,use_bn=True,name="conv_3")res=self.SENet(res)if x.shape.as_list()[-1]!=channels[2]:x=self.Conv2d(x,channels[2],[1,1],activation=None,use_bn=False,name="conv_linear")return tf.nn.relu(res+x)

结果暂时未出,待更新

(梳理)用Tensorflow实现SE-ResNet(SENet ResNet ResNeXt VGG16)的数据输入,训练,预测的完整代码框架(cifar10准确率90%)相关推荐

  1. TensorFlow学习笔记(十一)读取自己的数据进行训练

    1. 线性关系 数据csv文件读取 x,y 1,2 4,5 6,11 3,6 4,7 5,12 7,13 10,21 11,23 24,50 45,89 50,101 55,111 60,123 70 ...

  2. 【图像分类案例】(1) ResNeXt 交通标志四分类,附Tensorflow完整代码

    各位同学好,今天和大家分享一下如何使用 Tensorflow 构建 ResNeXt 神经网络模型,通过案例实战 ResNeXt 的训练以及预测过程.每个小节的末尾有网络.训练.预测的完整代码.想要数据 ...

  3. [深度学习-实践]Tensorflow 2.x应用ResNet SeNet网络训练cifar10数据集的模型在测试集上准确率 86%-87%,含完整代码

    环境 tensorflow 2.1 最好用GPU Cifar10数据集 CIFAR-10 数据集的分类是机器学习中一个公开的基准测试问题.任务的目标对一组32x32 RGB的图像进行分类,这个数据集涵 ...

  4. [深度学习-TF2实践]应用Tensorflow2.x训练ResNet,SeNet和Inception模型在cifar10,测试集上准确率88.6%

    环境 tensorflow 2.1 最好用GPU Cifar10数据集 CIFAR-10 数据集的分类是机器学习中一个公开的基准测试问题.任务的目标对一组32x32 RGB的图像进行分类,这个数据集涵 ...

  5. TensorFlow笔记(9) ResNet

    TensorFlow笔记(9) ResNet 1. 残差网络分类问题 2. 数据读取 3. 构建模型 4. 训练模型 5. 评估模型 6. 模型预测 1. 残差网络分类问题 非常深的神经网络是很难训练 ...

  6. DL:关于深度学习常用数据集中训练好的权重文件(Deeplab v3、MobileNet、InceptionV3、VGG系列、ResNet、Mask R-CNN )下载地址集合(持续更新)

    DL:关于深度学习常用数据集中训练好的权重文件(Deeplab v3.MobileNet.InceptionV3.VGG系列.ResNet.Mask R-CNN )下载地址集合(持续更新) 目录 基于 ...

  7. DL之ResNet:ResNet算法的简介(论文介绍)、架构详解、案例应用等配图集合之详细攻略

    DL之ResNet:ResNet算法的简介(论文介绍).架构详解.案例应用等配图集合之详细攻略 目录 ResNet算法的简介 1.比赛结果-ResNets @ ILSVRC & COCO 20 ...

  8. Caffe 议事(一):从零开始搭建 ResNet 之 残差网络结构介绍和数据准备

    声明:Caffe 系列文章是我们实验室 黄佳斌 大神所写的内部学习文档,已经获得他的授权允许. 本参考资料是在 Ubuntu14.04 版本下进行,并且默认 Caffe 所需的环境已经配置好,下面教大 ...

  9. 【神经网络】(17) EfficientNet 代码复现,网络解析,附Tensorflow完整代码

    各位同学好,今天和大家分享一下如何使用 Tensorflow 复现 EfficientNet 卷积神经网络模型. EfficientNet 的网络结构和 MobileNetV3 比较相似,建议大家在学 ...

  10. 【神经网络】(16) MobileNetV3 代码复现,网络解析,附Tensorflow完整代码

    各位同学好,今天和大家分享一下如何使用 Tensorflow 构建 MobileNetV3 轻量化网络模型. MobileNetV3 做了如下改动(1)更新了V2中的逆转残差结构:(2)使用NAS搜索 ...

最新文章

  1. 一起谈.NET技术,微软PDC10:大牛谈ASP.NET和C#技术走向
  2. gpu服务器厂家_服务器内存和显存知识你了解多少
  3. Linux系统上传文件与下载文件命令
  4. Android基础---学习历程【上课用到的资源---学期!汇总!整理】【课本源码、课后习题答案、上课课件与录播】
  5. Kali更新源 - 由于没有公钥,无法验证下列签名: NO_PUBKEY ED444FF07D8D0BF6
  6. 【转】漫画:Bitmap算法
  7. 用python进行自然语言处理_Python自然语言处理示例:SVM和贝叶斯分类
  8. java比较equlse_java基础知识要点
  9. 带父节点的平衡二叉树_Python算法系列—深度优先遍历算法【二叉树】
  10. MySQL 左右两表比较问题
  11. java进程因机器内存不足被系统kill的定位
  12. jsp页面ajax用法,JSP页面如何使用ajax实现局部刷新
  13. 清华大学 TUNA 协会
  14. win2008server R2 x64 部署.net core到IIS--ASP .NET Core HTTP Error 502.5 – Process Failure
  15. 智能优化算法:阿基米德优化算法 -附代码
  16. 部署桌面虚拟化时要考虑的因素
  17. 黑马程序员顺义校区php_2018黑马整套php视频教程
  18. linux运行maya,Debian5.0下成功安装Maya2009!!
  19. python 局域网传文件_Python+pyftpdlib实现局域网文件互传代码示例
  20. 射频识别技术软硬件系统研制

热门文章

  1. Mac打开终端自动运行命令
  2. Mac 怎么打开两个终端
  3. Activity的启动流程分析与总结
  4. 【公众号】微信进入公众号链接自动获取授权登陆
  5. 如何在linux下编写代码(非常详细)
  6. Element el-cascader 级联选择器详解
  7. PS(Photoshop)去水印的方法
  8. 如何在Excel里输入可以打钩的选择框?
  9. python爬虫反虫之setcookie
  10. 概念二 python3 中子类继承父类