總結:
https://blog.csdn.net/weixin_43624538/article/details/84963116
https://www.cnblogs.com/eniac1946/p/8669937.html
代碼參考:
https://blog.csdn.net/shankezh/article/details/89088085
設計原則
- 2.1避免特徵表示瓶頸,尤其是在網絡的前面。要避免嚴重壓縮導致的瓶頸。特徵表示尺寸應該溫和的減少,從輸入端到輸出端。特徵表示的維度只是一個粗淺的信息量表示,它丟掉了一些重要的因素如相關性結構。
- 2.2高緯信息更適合在網絡的局部處理。在卷積網絡中逐步增加非線性激活響應可以解耦合更多的特徵,那麼網絡就會訓練的更快。
- 2.3空間聚合可以通過低緯嵌入,不會導致網絡表示能力的降低。例如在進行大尺寸的卷積(如3*3)之前,我們可以在空間聚合前先對輸入信息進行降維處理,如果這些信號是容易壓縮的,那麼降維甚至可以加快學習速度。
- 2.4平衡好網絡的深度和寬度。通過平衡網絡每層濾波器的個數和網絡的層數可以是網絡達到最佳性能。增加網絡的寬度和深度都會提升網絡的性能,但是兩者並行增加獲得的性能提升是最大的。
import tensorflow as tf import numpy as np from sklearn.model_selection import train_test_split import tensorflow.contrib.slim as slim class InceptionV3(object): def __init__(self): self.n_input = 299*299*3 self.n_classes = 10 self.batch_size = 10 self.training_iters = 20 self.display_step = 20 self.learning_rate = 0.001 def conv2d(self,x,filters,k_size,stride=[1,1],padding='SAME',activation = tf.nn.relu,scope='conv2d'): return tf.layers.conv2d(inputs=x,filters=filters,kernel_size=k_size, strides=stride,padding=padding,name=scope,activation=activation) def maxpool2d(self,x,pool_size=[2,2],stride=[2,2],padding='same',scope='conv2d'): return tf.layers.max_pooling2d(inputs=x,pool_size=pool_size,strides=stride,padding=padding,name=scope) def dropoutx(self,x,d_rate): return tf.layers.dropout(x,rate=d_rate) def avgpool2d(self,x,pool_size=[1,1],stride=[1,1],padding='same',scope='avgpool2d'): return tf.layers.average_pooling2d(x,pool_size=pool_size,strides=stride,padding=padding,name=scope) def inception_module_v3_1(self,x,filter_num,stride=[1,1],scope='inception_moudle_v3_1'): with tf.variable_scope(scope): with tf.variable_scope("bh1"): bh1 = self.conv2d(x,filters=filter_num[0],k_size=[1,1],stride=stride,scope='bh1_conv1_1x1') with tf.variable_scope("bh2"): bh2 = self.avgpool2d(x,pool_size=[1,1],stride=stride,scope='bh2_avg_3x3') bh2 = self.conv2d(bh2,filters=filter_num[2],k_size=[3,3],stride=stride,scope='bh2_conv_1x1') with tf.variable_scope("bh3"): bh3 = self.conv2d(x,filters=filter_num[3],k_size=[1,1],stride=stride,scope='bh3_conv1_1x1') bh3 = self.conv2d(bh3,filters=filter_num[4],k_size=[5,5],stride=stride,scope='bh3_conv2_3x3') with tf.variable_scope("bh4"): bh4 = self.conv2d(x,filters=filter_num[4],k_size=[1,1],stride=stride,scope='bh4_conv1_1x1') bh4 = self.conv2d(bh4,filters=filter_num[5],k_size=[3,3],stride=stride,scope='bh4_conv2_3x3') bh4 = self.conv2d(bh4,filters=filter_num[6],k_size=[3,3],stride=stride,scope='bh4_conv3_3x3') return tf.concat([bh1,bh2,bh3,bh4],axis=3) def inception_moudle_v3_2(self,net, scope, filter_num, stride=[1,1]): with tf.variable_scope(scope): with tf.variable_scope("bh1"): bh1 = self.conv2d(net, filters=filter_num[0], k_size=[1, 1], stride=stride, scope="bh1_conv_1x1") with tf.variable_scope("bh2"): bh2 = self.avgpool2d(net, [3, 3], stride=stride, scope='bh2_avg_3x3') bh2 = self.conv2d(bh2, filter_num[1], k_size=[1, 1], stride=stride, scope='bh2_conv_1x1') with tf.variable_scope("bh3"): bh3 = self.conv2d(net, filter_num[2], k_size=[1, 1], stride=stride, scope='bh3_conv1_1x1') bh3 = self.conv2d(bh3, filter_num[3], k_size=[1, 7], stride=stride, scope='bh3_conv2_1x7') bh3 = self.conv2d(bh3, filter_num[4], k_size=[7, 1], stride=stride, scope='bh3_conv3_7x1') with tf.variable_scope("bh4"): bh4 = self.conv2d(net, filter_num[5], [1, 1], stride=stride, scope='bh4_conv1_1x1') bh4 = self.conv2d(bh4, filter_num[6], [1, 7], stride=stride, scope='bh4_conv2_1x7') bh4 = self.conv2d(bh4, filter_num[7], [7, 1], stride=stride, scope='bh4_conv3_7x1') bh4 = self.conv2d(bh4, filter_num[8], [1, 7], stride=stride, scope='bh4_conv4_1x7') bh4 = self.conv2d(bh4, filter_num[9], [7, 1], stride=stride, scope='bh4_conv5_7x1') net = tf.concat([bh1, bh2, bh3, bh4], axis=3) return net def inception_moudle_v3_3(self,net, scope, filter_num, stride=[1,1]): with tf.variable_scope(scope): with tf.variable_scope("bh1"): bh1 = self.conv2d(net, filter_num[0], [1, 1], stride=stride, scope='bh1_conv_1x1') with tf.variable_scope("bh2"): bh2 = self.avgpool2d(net, [3, 3], stride=stride, scope='bh2_avg_3x3') bh2 = self.conv2d(bh2, filter_num[1], [1, 1], stride=stride, scope='bh2_conv_1x1') with tf.variable_scope("bh3"): bh3 = self.conv2d(net, filter_num[2], [1, 1], stride=stride, scope='bh3_conv1_1x1') bh3_1 = self.conv2d(bh3, filter_num[3], [3, 1], stride=stride, scope='bh3_conv2_3x1') bh3_2 = self.conv2d(bh3, filter_num[4], [1, 3], stride=stride, scope='bh3_conv2_1x3') with tf.variable_scope("bh4"): bh4 = self.conv2d(net, filter_num[5], [1, 1], stride=stride, scope='bh4_conv1_1x1') bh4 = self.conv2d(bh4, filter_num[6], [3, 3], stride=stride, scope='bh4_conv2_3x3') bh4_1 = self.conv2d(bh4, filter_num[7], [3, 1], stride=stride, scope='bh4_conv3_3x1') bh4_2 = self.conv2d(bh4, filter_num[8], [1, 3], stride=stride, scope='bh4_conv3_1x3') net = tf.concat([bh1, bh2, bh3_1, bh3_2, bh4_1, bh4_2], axis=3) return net def inception_moudle_v3_reduce(self,net, scope, filter_num): with tf.variable_scope(scope): with tf.variable_scope("bh1"): bh1 = self.avgpool2d(net, [3, 3], stride=[2,2], padding='VALID', scope="bh1_max_3x3") with tf.variable_scope("bh2"): bh2 = self.conv2d(net, filter_num[0], [1, 1], stride=[1,1], scope='bh2_conv1_1x1') bh2 = self.conv2d(bh2, filter_num[1], [3, 3], stride=[2,2], padding='VALID', scope='bh2_conv2_3x3') with tf.variable_scope("bh3"): bh3 = self.conv2d(net, filter_num[2], [1, 1], stride=[1,1], scope='bh3_conv1_1x1') bh3 = self.conv2d(bh3, filter_num[3], [3, 3], stride=[1,1], scope='bh3_conv2_3x3') bh3 = self.conv2d(bh3, filter_num[4], [3, 3], stride=[2,2], padding='VALID', scope='bh3_conv3_3x3') net = tf.concat([bh1, bh2, bh3], axis=3) return net def set_net(self,x,keep_prob,is_train=True,spatital_squeeze=True): check_point = {} net = tf.reshape(x,[-1,299,299,3]) net = self.conv2d(net, 32, [3, 3], stride=[2,2], scope="layer1") # 149x149 net = self.conv2d(net, 32, [3, 3], scope='layer2') # 147x147 net = self.conv2d(net, 64, [3, 3], padding='SAME', scope='layer3') # 147x147 net = self.maxpool2d(net, [3, 3], stride=[2,2],scope='layer4') # 73x73 net = self.conv2d(net, 80, [3, 3], scope='layer5') # 71x71 net = self.conv2d(net, 192, [3, 3], stride=[2,2],scope='layer6') # 35x35 net = self.conv2d(net, 288, [3, 3], scope='layer7') # 3 x inception net = self.inception_module_v3_1(net, scope='layer8', filter_num=[64, 32, 48, 64, 64, 96, 96]) # 35x35 net = self.inception_module_v3_1(net, scope='layer11', filter_num=[64, 64, 48, 64, 64, 96, 96]) net = self.inception_module_v3_1(net, scope='layer14', filter_num=[64, 64, 48, 64, 64, 96, 96]) print('1111',net) # 5 x inception net = self.inception_moudle_v3_reduce(net, scope='layer17', filter_num=[192, 384, 64, 96, 96]) # 17x17 print('2222',net) net = self.inception_moudle_v3_2(net, scope='layer20', filter_num=[192, 192, 128, 128, 192, 128, 128, 128, 128, 192]) net = self.inception_moudle_v3_2(net, scope='layer25', filter_num=[192, 192, 160, 160, 192, 160, 160, 160, 160, 192]) net = self.inception_moudle_v3_2(net, scope='layer30', filter_num=[192, 192, 160, 160, 192, 160, 160, 160, 160, 192]) net = self.inception_moudle_v3_2(net, scope='layer35', filter_num=[192, 192, 160, 160, 192, 160, 160, 160, 160, 192]) print(net) # 3 x inception net = self.inception_moudle_v3_reduce(net, scope='layer40', filter_num=[192, 320, 192, 192, 192]) # 8x8 net = self.inception_moudle_v3_3(net, scope='layer43', filter_num=[320, 192, 384, 384, 384, 448, 384, 384, 384]) net = self.inception_moudle_v3_3(net, scope='layer46', filter_num=[320, 192, 384, 384, 384, 448, 384, 384, 384]) print(net) net = self.avgpool2d(net, [8, 8], padding='VALID', scope='layer49') net = slim.dropout(net) net = slim.conv2d(net, self.n_classes, [1, 1], activation_fn=None, normalizer_fn=None, scope='layer50') print(net) if spatital_squeeze: net = tf.squeeze(net, [1, 2], name='squeeze') net = slim.softmax(net, scope='softmax') return net def inceptionv1_prediction(self, X,Y, scope='vgg'): X_train, X_vaild, y_train, y_vaild = train_test_split(X, Y, test_size=0.2) x = tf.placeholder(tf.float32, [None, self.n_input]) y = tf.placeholder(tf.float32, [None, self.n_classes]) pred = self.set_net(x,0.8) # pred是計算完的值,此時還沒歸一化 a = tf.nn.softmax(pred) # a是歸一化後的值。 # 定義損失函數和學習步驟 cost = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits=pred, labels=y)) # 這個是損失loss optimizer = tf.train.AdamOptimizer(learning_rate=self.learning_rate).minimize(cost) # 最小化loss # 測試網絡 correct_pred = tf.equal(tf.argmax(pred, 1), tf.argmax(y, 1)) accuracy = tf.reduce_mean(tf.cast(correct_pred, tf.float32)) # 初始化所有的共享變量 init = tf.initialize_all_variables() with tf.Session() as sess: sess.run(init) step = 1 # Keep training until reach max iterations while step * self.batch_size < self.training_iters: # 直到達到最大迭代次數,沒考慮梯度!!! batch_xs, batch_ys = X_train[self.batch_size*(step-1):self.batch_size*step],y_train[self.batch_size*(step-1):self.batch_size*step] batch_xs = np.reshape(batch_xs,(-1,self.n_input)) print('~!!!!!!!!',batch_xs.shape) print(batch_ys.shape) # 獲取批數據 sess.run(optimizer, feed_dict={x: batch_xs, y: batch_ys}) if step % self.display_step == 0: # 每一步裏有64batch,64*20=1280 # 計算精度 acc = sess.run(accuracy, feed_dict={x: batch_xs, y: batch_ys}) # 計算損失值 loss = sess.run(cost, feed_dict={x: batch_xs, y: batch_ys}) print("Iter " + str(step * self.batch_size) + ", Minibatch Loss= " + "{:.6f}".format( loss) + ", Training Accuracy = " + "{:.5f}".format(acc)) step += 1 print("Optimization Finished!") # 計算測試精度 X_vaild = np.reshape(X_vaild, (-1, self.n_input)) print("Testing Accuracy:", sess.run(accuracy, feed_dict={x: X_vaild[:256], y: y_vaild[:256], })) # 拿前256個來測試 print("Testing Result:", sess.run(a, feed_dict={x: X_vaild[63:64], y: y_vaild[63:64], })) # 數組範圍,從0開始,含左不含右 print(y_vaild[63:64])