class VGG16_Mode():
""" create vgg16 network use tensorflow
VGG16 network structure:
(conv 3x3 64)=>(conv 3x3 64, pool/2)
(conv 3x3 128)=>(conv 3x3 128, pool/2)
(conv 3x3 256)=>(conv 3x3 256)=>(conv 3x3 256)=>(conv 3x3 256, pool/2)
(conv 3x3 512)=>(conv 3x3 512)=>(conv 3x3 512)=>(conv 3x3 512, pool/2)
(fc 4096)=>(fc 4096)=>(fc classes)
"""
def variable_summaries(self, var, name):
with tf.name_scope('summaries'):
tf.summary.histogram(name, var)
mean = tf.reduce_mean(var)
tf.summary.scalar('mean/' + name, mean)
stddev = tf.sqrt(tf.reduce_mean(tf.square(var - mean)))
tf.summary.scalar('stddev/' + name, stddev)
def conv_layer(self, data, ksize, stride, name, w_biases = False,padding = "SAME"):
with tf.variable_scope(name) as scope:
with tf.name_scope(name):
with tf.name_scope("weights"):
w_init = tf.contrib.layers.xavier_initializer()
w = tf.get_variable(shape= ksize, initializer= w_init,name= 'w')
self.variable_summaries(w, name + "/weights")
with tf.name_scope("biases"):
biases = tf.Variable(tf.constant(0.0, shape=[ksize[3]], dtype=tf.float32), 'biases')
self.variable_summaries(biases, name + "/biases")
with tf.name_scope("Wx_plus_b"):
if w_biases == False:
cov = tf.nn.conv2d(input= data, filter= w, strides= stride, padding= padding)
else:
cov = tf.nn.conv2d(input= data,filter= w, stride= stride,padding= padding) + biases
# 记录神经网络节点输出在经过激活函数之后的分布。
tf.summary.histogram(name + '/activations', cov)
return cov
def pool_layer(self, data, ksize, stride, name, padding= 'VALID'):
with tf.variable_scope(name) as scope:
max_pool = tf.nn.max_pool(value= data, ksize= ksize, strides= stride,padding= padding)
return max_pool
def flatten(self,data):
[a,b,c,d] = data.shape
ft = tf.reshape(data,[-1,b*c*d])
return ft
def fc_layer(self,data,name,fc_dims):
with tf.variable_scope(name) as scope:
with tf.name_scope(name):
with tf.name_scope("weights"):
w_init = tf.contrib.layers.xavier_initializer()
w = tf.get_variable(shape=[data.shape[1],fc_dims],name= 'w',initializer=w_init)
self.variable_summaries(w, name + "/weights")
with tf.name_scope("biases"):
biases = tf.Variable(tf.constant(0.0, shape=[fc_dims], dtype=tf.float32), 'biases')
self.variable_summaries(biases, name + "/biases")
with tf.name_scope("Wx_plus_b"):
fc = tf.nn.relu(tf.matmul(data,w)+ biases)
tf.summary.histogram(name + '/pre_activations', tf.matmul(data,w)+ biases)
# 记录神经网络节点输出在经过激活函数之后的分布。
tf.summary.histogram(name + '/activations', fc)
return fc
def finlaout_layer(self,data,name,fc_dims):
with tf.variable_scope(name, reuse=tf.AUTO_REUSE):
with tf.name_scope(name):
with tf.name_scope("weights"):
w_init = tf.contrib.layers.xavier_initializer()
w = tf.get_variable(shape=[data.shape[1],fc_dims],name= 'w',initializer=w_init)
self.variable_summaries(w, name + "/weights")
with tf.name_scope("biases"):
biases = tf.Variable(tf.constant(0.0, shape=[fc_dims], dtype=tf.float32), 'biases')
self.variable_summaries(biases, name + "/biases")
with tf.name_scope("Wx_plus_b"):
fc = tf.nn.softmax(tf.matmul(data,w)+ biases)
tf.summary.histogram(name + '/pre_activations', tf.matmul(data,w)+ biases)
# 记录神经网络节点输出在经过激活函数之后的分布。
tf.summary.histogram(name + '/activations', fc)
return fc
def model_bulid(self, height, width, channel,classes):
with tf.name_scope("input"):
x = tf.placeholder(dtype= tf.float32, shape = [None,height,width,channel])
y = tf.placeholder(dtype= tf.float32 ,shape=[None,classes])
tf.summary.image("input", x, 50)
# conv 1 ,if image Nx465x128x1 ,(conv 3x3 64)=>(conv 3x3 64, pool/2)
with tf.name_scope("conv1"):
conv1_1 = tf.nn.relu(self.conv_layer(x,ksize= [3,3,1,64],stride=[1,1,1,1],padding="SAME",name="conv1_1"))
conv1_2 = tf.nn.relu(self.conv_layer(conv1_1,ksize=[3,3,64,64],stride=[1,1,1,1],padding="SAME",name="conv1_2")) # Nx465x128x1 ==> Nx465x128x64
pool1_1 = self.pool_layer(conv1_2,ksize=[1,2,2,1],stride=[1,2,2,1],name="pool1_1") # N*232x64x64
# conv 2,(conv 3x3 128)=>(conv 3x3 128, pool/2)
with tf.name_scope("conv2"):
conv2_1 = tf.nn.relu(self.conv_layer(pool1_1,ksize=[3,3,64,128],stride=[1,1,1,1],padding="SAME",name="conv2_1"))
conv2_2 = tf.nn.relu(self.conv_layer(conv2_1,ksize=[3,3,128,128],stride=[1,1,1,1],padding="SAME",name="conv2_2")) # Nx232x64x128
pool2_1 = self.pool_layer(conv2_2,ksize=[1,2,2,1],stride=[1,2,2,1],name="pool2_1") # Nx116x32x128
# conv 3,(conv 3x3 256)=>(conv 3x3 256)=>(conv 3x3 256)=>(conv 3x3 256, pool/2)
with tf.name_scope("conv3"):
conv3_1 = tf.nn.relu(self.conv_layer(pool2_1,ksize=[3,3,128,256],stride=[1,1,1,1],padding="SAME",name="conv3_1"))
conv3_2 = tf.nn.relu(self.conv_layer(conv3_1,ksize=[3,3,256,256],stride=[1,1,1,1],padding="SAME",name="conv3_2"))
conv3_3 = tf.nn.relu(self.conv_layer(conv3_2,ksize=[3,3,256,256],stride=[1,1,1,1],padding="SAME",name="conv3_3"))
conv3_4 = tf.nn.relu(self.conv_layer(conv3_3,ksize=[3,3,256,256],stride=[1,1,1,1],padding="SAME",name="conv3_4")) # NX116X32X256
pool3_1 = self.pool_layer(conv3_4,ksize=[1,2,2,1],stride=[1,2,2,1],name="pool3_1") # Nx58x16x256
#conv 4,(conv 3x3 512) = > (conv 3x3 512) = > (conv 3x3 512) = > (conv 3x3 512, pool / 2)
with tf.name_scope("conv4"):
conv4_1 = tf.nn.relu(self.conv_layer(pool3_1,ksize=[3,3,256,512],stride=[1,1,1,1],padding="SAME",name="conv4_1"))
conv4_2 = tf.nn.relu(self.conv_layer(conv4_1,ksize=[3,3,512,512],stride=[1,1,1,1],padding="SAME",name="conv4_2"))
conv4_3 = tf.nn.relu(self.conv_layer(conv4_2,ksize=[3,3,512,512],stride=[1,1,1,1],padding="SAME",name="conv4_3"))
conv4_4 = tf.nn.relu(self.conv_layer(conv4_3,ksize=[3,3,512,512],stride=[1,1,1,1],padding="SAME",name="conv4_4")) # Nx58x16x512
pool4_1 = self.pool_layer(conv4_4,ksize=[1,2,2,1],stride=[1,2,2,1],name="pool4_1") # Nx29x8x512
# Flatten
with tf.name_scope("Flatten"):
ft = self.flatten(pool4_1)
# Dense layer,(fc 4096)=>(fc 4096)=>(fc classes)
fc1 = self.fc_layer(ft,fc_dims=4096,name="fc1")
fc2 = self.fc_layer(fc1,fc_dims=4096,name="fc2")
# fc3 = self.fc_layer(fc2,fc_dims=10,name="fc3")
with tf.name_scope("Final_Output"):
finaloutput = self.finlaout_layer(fc2,fc_dims=10,name="final")
# cost
with tf.name_scope("cross_entropy"):
cross_entropy = tf.losses.softmax_cross_entropy(y,finaloutput)
tf.summary.scalar("cross_entropy", cross_entropy)
# optimize
LEARNING_RATE_BASE = 0.0001
LEARNING_RATE_DECAY = 0.000001
LEARNING_RATE_STEP = 1000
#MOVING_AVERAGE_DECAY = 0.99
global_steps = tf.Variable(0, trainable=False)
# 处理滑动平均的命名空间。
#with tf.name_scope("moving_average"):
#variable_averages = tf.train.ExponentialMovingAverage(MOVING_AVERAGE_DECAY, global_steps)
#variables_averages_op = variable_averages.apply(tf.trainable_variables())
with tf.name_scope("train"):
learning_rate = tf.train.exponential_decay(LEARNING_RATE_BASE,
global_steps,
LEARNING_RATE_STEP,
LEARNING_RATE_DECAY,
staircase=True)
with tf.variable_scope(tf.get_variable_scope(), reuse=tf.AUTO_REUSE):
optimize = tf.train.AdamOptimizer(learning_rate=learning_rate).minimize(cross_entropy,global_step=global_steps)
with tf.name_scope("Accuracy"):
with tf.name_scope("prediction_label"):
prediction_label = finaloutput
with tf.name_scope("correct_prediction"):
correct_prediction = tf.equal(tf.argmax(prediction_label, 1), tf.argmax(y, 1))
with tf.name_scope("accurary"):
accurary = tf.reduce_mean(tf.cast(correct_prediction, dtype=tf.float32))
with tf.name_scope("correct_times_in_batch"):
correct_times_in_batch = tf.reduce_mean(tf.cast(correct_prediction, dtype=tf.int32))
tf.summary.scalar("Accuracy", accurary)
self.merged = tf.summary.merge_all()
self.init_sess()
self.writer = tf.summary.FileWriter("log", self.sess.graph)
return dict(
x=x,
y=y,
optimize=optimize,
prediction_label=prediction_label,
correct_times_in_batch=correct_times_in_batch,
cross_entropy=cross_entropy,
accurary=accurary,
global_steps=global_steps,
Flatten=ft
)
def init_sess(self):
init = tf.group(tf.global_variables_initializer(),tf.local_variables_initializer())
self.sess = tf.Session()
self.sess.run(init)
def train_network(self,graph,x_train,y_train):
# Tensorfolw Adding more and more nodes to the previous graph results in a larger and larger memory footprint
# reset graph
tf.reset_default_graph()
self.sess.run(graph['optimize'],feed_dict={graph['x']:x_train, graph['y']:y_train})
def load_data(self):
self.mnist = input_data.read_data_sets('MNIST_data', one_hot=True)
def train(self, n_epcho=1000, imgsize=[28,28], chnnels=1, n_classes=10,batch_size=500):
imgsize1, imgsize2 = imgsize
#self.init_sess()
g = self.model_bulid(28, 28, 1, 10)
#writer = g["writer"]
for i in range(n_epcho):
batch_xs, batch_ys = self.mnist.train.next_batch(500)
batch_xs = np.reshape(batch_xs,[-1,28,28,1])
#self.train_network(g, batch_xs, batch_ys)
if i % 1000 == 0:
# 配置运行时需要记录的信息。
#run_options = tf.RunOptions(trace_level=tf.RunOptions.FULL_TRACE)
# 运行时记录运行信息的proto。
#run_metadata = tf.RunMetadata()
summary, _, cross_entropy, step, accuracy = self.sess.run([self.merged,
g["optimize"],
g["cross_entropy"],
g["global_steps"],
g["accurary"]],
feed_dict={g["x"]: batch_xs, g["y"]: batch_ys}
)
#options=run_options,
# run_metadata=run_metadata
#self.writer.add_run_metadata(run_metadata=run_metadata, tag=("tag%d" % i), global_step=i)
print("After %d training step(s), loss on training batch is %g." % (int(step/100), cross_entropy))
else:
summary, _, cross_entropy, step, accuracy = self.sess.run([self.merged,
g["optimize"],
g["cross_entropy"],
g["global_steps"],
g["accurary"]],
feed_dict={g["x"]: batch_xs, g["y"]: batch_ys})
self.writer.add_summary(summary, i)
self.save_model(g)
self.close()
def close(self):
self.sess.close()
self.writer.close()
def save_model(self, graph):
export_path = "pb_model/1"
if os.path.exists(export_path):
os.system("rm -rf "+ export_path)
print("Export the model to {}".format(export_path))
# 构建需要在新会话中恢复的变量的 TensorInfo protobuf
X_TensorInfo = sm.utils.build_tensor_info(graph["x"])
y_true_TensorInfo = sm.utils.build_tensor_info(graph["y"])
features_TensorInfo = sm.utils.build_tensor_info(graph["Flatten"])
y_pred_cls_TensorInfo = sm.utils.build_tensor_info(graph["prediction_label"])
accu_TensorInfo = sm.utils.build_tensor_info(graph["accurary"])
# 构建 SignatureDef protobuf
model_signature = sm.signature_def_utils.build_signature_def(
inputs={'input_1': X_TensorInfo,
'input_2': y_true_TensorInfo},
outputs={'output_1': features_TensorInfo,
'output_2': y_pred_cls_TensorInfo,
'output_3': accu_TensorInfo},method_name=signature_constants.PREDICT_METHOD_NAME)
try:
legacy_init_op = tf.group(
tf.tables_initializer(), name='legacy_init_op')
builder = saved_model_builder.SavedModelBuilder(export_path)
builder.add_meta_graph_and_variables(
self.sess, [tag_constants.SERVING],
clear_devices=True,
signature_def_map={
signature_constants.DEFAULT_SERVING_SIGNATURE_DEF_KEY:
model_signature,
},
legacy_init_op=legacy_init_op)
builder.save()
except Exception as e:
print("Fail to export saved model, exception: {}".format(e))
vgg_model = VGG16_Mode() # 创建模型
vgg_model.load_data() # 加载数据
vgg_model.train(n_epcho=20000) # 训练模型
#加载pb模型
def load_pb(data, labels):
session = tf.Session(graph=tf.Graph())
model_file_path = "model"
meta_graph = tf.saved_model.loader.load(session, [tf.saved_model.tag_constants.SERVING], model_file_path)
model_graph_signature = list(meta_graph.signature_def.items())[0][1]
output_tensor_names = []
output_op_names = []
for output_item in model_graph_signature.outputs.items():
output_op_name = output_item[0]
output_op_names.append(output_op_name)
output_tensor_name = output_item[1].name
output_tensor_names.append(output_tensor_name)
print("load model finish!")
sentences = {}
# 测试pb模型
sentences["input_1"] = data
sentences["input_2"] = labels
feed_dict_map = {}
for input_item in model_graph_signature.inputs.items():
input_op_name = input_item[0]
input_tensor_name = input_item[1].name
feed_dict_map[input_tensor_name] = sentences[input_op_name]
result = session.run(output_tensor_names, feed_dict=feed_dict_map)
return result
show_function = ShowResult()
show_example = show_function.show(img_data=mnist.test.images,
img_labels=mnist.test.labels,
y_pred=result[1],
show_example_errors=True,
show_confusion_matrix=True,
show_exmaple_random=True)
from performace_evaluation import chswn
evaluation = chswn()
classes=[0,1,2,3,4,5,6,7,8,9]
y_predict = evaluation.label_binarize_convert(np.argmax(result[1],axis=1), classes)
evaluation.Average_precision_score(mnist.test.labels, y_predict, classes)
evaluation.Precision_Recall_curve_to_multi_class(classes=classes)
8、实验结果