Using TensorFlow to implement residual network ResNet-50

Source: Internet
Author: User
Tags python list

This article explains the use of TensorFlow to implement residual network resnet-50. The focus is not on the theoretical part, but on the implementation part of the code. There are other open source implementations on the GitHub, and if you want to run your own data directly using the code, it's not recommended to use my code. But if you want to learn ResNet code implementation ideas, then reading this article will be a good choice, because the code of this article is very clear thinking. If you have just finished reading ResNet's paper, it is highly recommended that you further learn how to use code to implement ResNet. This article contains the source data set.

ResNet just added shortcut to CNN, so ResNet and CNN are very similar. 1. Model

The following will be achieved is resnet-50. The following is an overall model diagram of the network model. The conv represents the convolution layer, the Batch norm represents Batch normalized layer, and the ID block represents the identity blocks, which are composed of multiple layers, specifically the second figure. The Conv block represents the convolution blocks, which are composed of multiple layers. In order to make the model structure more clear, we extracted the conv block and ID blocks two ' chunks ', respectively, to encapsulate them into functions.

If you do not understand batch norm, you can temporarily filter this part of the content, you can see it as a special layer, it does not change the dimensions of the data. This will not affect the understanding of ResNet implementations.

See the third diagram in detail.

The diagram above shows the overall structure of the RESNET-50


The figure above represents conv block


The figure above represents the ID block 2. Data

Enter a gesture image data similar to the one shown above, with a total of 6 classes. The data given has been processed and is '. h5 ' format. There are 1080 photos, 120 test data. Each picture is a 64x64 RGB image. The specific data format is:

Number of Training examples = 1080 number of
Test examples =
x_train shape: (1080,, 3)
Y_train Shap E: (1080, 6)
x_test shape: (3)
y_test shape: (6)
x train Max,  0.956, x train min,  0. 015
x Test max,  0.94 x Test min,  0.011
3. Target

Train a model that can discriminate the number represented by the finger in the picture. In essence, this is a multiple classification problem. So, the input of the model is a 64x64x3 picture; the output layer of the model is 6 nodes, each node represents a classification. 4. Model Implementation

The implementation of the identity block, for Figure 2 above. It should be noted that X_shortcut first saved the incoming data and then added X_shortcut to the end of the function. Besides this, the other points are the same as CNN.

    def identity_block (self, x_input, kernel_size, In_filter, Out_filters, stage, block, training): "" "Im Plementation of the identity block as defined in Figure 3 arguments:x--Input tensor to shape (m, n_h_p Rev, N_w_prev, N_c_prev) kernel_size--integer, specifying the shape of the middle CONV ' s window for the main pat H Filters--python list of integers, defining the number of filters in the CONV layers of the main path s Tage--integer, used to name the layers, depending on their position at the network block--String/character, US
        Ed to name the layers, depending on their position in the network training--Train or test Returns:
        X--Output of the identity block, tensor of shape (N_h, N_w, N_c) "" "# Defining name basis
            Block_name = ' res ' + str (stage) + Block F1, F2, F3 = Out_filters with Tf.variable_scope (block_name): X_shortcut = x_inPut #first w_conv1 = self.weight_variable ([1, 1, In_filter, F1]) X = tf.nn.conv2d (x_i Nput, W_conv1, strides=[1, 1, 1, 1], padding= ' SAME ') X = tf.layers.batch_normalization (x, axis=3, Training=tra ining) X = Tf.nn.relu (x) #second w_conv2 = self.weight_variable ([Kernel_size, Kernel_ Size, F1, F2]) x = tf.nn.conv2d (x, W_conv2, strides=[1, 1, 1, 1], padding= ' SAME ') x = tf.layers.ba Tch_normalization (x, axis=3, training=training) x = Tf.nn.relu (x) #third w_conv3 = s
            Elf.weight_variable ([1, 1, F2, F3]) X = tf.nn.conv2d (x, W_conv3, strides=[1, 1, 1, 1], padding= ' VALID ')  x = tf.layers.batch_normalization (x, axis=3, training=training) #final Step add = Tf.add (x, X_shortcut) Add_result = Tf.nn.relu (add) return Add_result

The following is conv block, which corresponds to picture 3 above.

    def convolutional_block (self, x_input, kernel_size, In_filter, Out_filters, stage, block, Training, stride=2): "" "Implementation of the convolutional block as defined in Figure 4 argumen TS:X--Input tensor of shape (M, N_h_prev, N_w_prev, N_c_prev) kernel_size--Integer, specifying the SH Ape of the Middle CONV ' s window for the main path filters--python list of integers, defining the number of Filte RS in the CONV layers of the main path stage--integer, used to name the layers, depending on their position in T
        He network blocks--string/character, used to name the layers, depending on their position in the network Training-Train or test stride-Integer, specifying the stride to be used returns:x-OUTPU T of the convolutional block, tensor of shape (N_h, N_w, N_c) "" ' # Defining name Basis Block_nam E = ' res ' + str (stage) + Blocks with Tf.variable_scope (block_name): F1, F2, F3 = out_filters X_shortcut = x_input  #first w_conv1 = self.weight_variable ([1, 1, In_filter, F1]) X = tf.nn.conv2d (X_input, W_conv1,strides=[1, Stride, stride, 1],padding= ' VALID ') x = tf.layers.batch_normalization (x, axis=3, training =training) X = Tf.nn.relu (x) #second w_conv2 = self.weight_variable ([Kernel_size, Ker Nel_size, F1, F2]) x = tf.nn.conv2d (x, W_conv2, strides=[1,1,1,1], padding= ' SAME ') x = tf.layers.b Atch_normalization (x, axis=3, training=training) x = Tf.nn.relu (x) #third w_conv3 = s
            Elf.weight_variable ([1,1, f2,f3]) X = tf.nn.conv2d (x, W_conv3, strides=[1, 1, 1,1], padding= ' VALID ') x = tf.layers.batch_normalization (x, axis=3, training=training) #shortcut path w_shortcut = SE Lf.weight_variable ([1, 1, In_filter, F3]) X_shortcut = tf.nn.conv2d (X_shortcut, W_shortcut, strides=[1, Stride, stride, 1], padding= ' V Alid ') #final add = Tf.add (x_shortcut, x) Add_result = Tf.nn.relu (add) retur N Add_result

The following is the consolidation of the model, which corresponds to figure 1 above.

    def deepnn (self, X_input, classes=6): "" "Implementation of the popular ResNet50 the following cture:conv2d-> batchnorm-> relu-> maxpool-> convblock-> idblock*2-> CONVBLOCK-> IDBLO Ck*3-> convblock-> idblock*5-> convblock-> idblock*2-> avgpool-> TOPLAYER Argumen 
        Ts:returns: "" "x = Tf.pad (X_input, tf.constant ([[0, 0], [3, 3,], [3, 3], [0, 0]]," constant ")

            With Tf.variable_scope (' reference '): training = Tf.placeholder (Tf.bool, name= ' training ') #stage 1 W_CONV1 = self.weight_variable ([7, 7, 3,]) x = tf.nn.conv2d (x, W_CONV1, Strides=[1, 2, 2, 1], padding= ' VALID ') x = tf.layers.batch_normalization (x, axis=3, training=training) x = tf. Nn.relu (x) x = Tf.nn.max_pool (x, Ksize=[1, 3, 3, 1], strides=[1, 2, 2, 1], padding= ' VALID ') assERT (x.get_shape () = = (X.get_shape () [0], A ()) #stage 2 x = Self.convolutional_block (x, 3, [256], 2, ' a ', training, stride=1) x = Self.identity_block (x, 3, 256, [+, 256], stage=2, Blo ck= ' B ', training=training) x = Self.identity_block (x, 3, 256, [, 256], stage=2, block= ' C ', Training=trai
            Ning) #stage 3 x = Self.convolutional_block (x, 3, 256, [128,128,512], 3, ' a ', training) x = Self.identity_block (x, 3, O, [128,128,512], 3, ' B ', training=training) x = Self.identity_block (x, 3, 3, ' C ', training=training, x = Self.identity_block (x, 3, 128,128,512, [128,128,512], 3, ' d ', train ing=training) #stage 4 x = Self.convolutional_block (x, 3, 4, [256, 256, 1024], training x = Self.identity_block (x, 3, 1024, [256, 256, 1024], 4, ' B ', training=training) x = Self.identi Ty_block (x, 3, 1024, [256, 256, 1024], 4, ' C ', training=training) x = Self.identity_block (x, 3, 1024, [256, 256, 1024], 4, ' d ', Traini  ng=training) x = Self.identity_block (x, 3, 1024, [256, 256, 1024], 4, ' e ', training=training) x = Self.identity_block (x, 3, 1024, [256, 256, 1024], 4, ' F ', training=training) #stage 5 x = SELF.C Onvolutional_block (x, 3, 1024, [3, 2048], 5, ' a ', training) x = Self.identity_block (x, 2048, 512, 5 2048], 5, ' B ', training=training) x = Self.identity_block (x, 3, 2048, [,, 2048], 5, ' C ', training=t Raining) x = Tf.nn.avg_pool (x, [1, 2, 2, 1], strides=[1,1,1,1], padding= ' VALID ') flatten = tf.la  Yers.flatten (x) x = Tf.layers.dense (Flatten, units=50, Activation=tf.nn.relu) # Dropout-controls
            The complexity of the model, prevents co-adaptation of # features. With Tf.name_scope (' Dropout '): KEEP_PROB = Tf.placeholder (tf.float32) x = Tf.nn.dropout (x, keep_prob) logits = Tf.layers.dense (x, U Nits=6, Activation=tf.nn.softmax) return logits, Keep_prob, training
5. Cost function

Use the cross entropy to compute the loss function and the cost function. There is no use of L2 regularization here.

    def cost (self, logits, labels): With
        tf.name_scope (' loss '):
            # cross_entropy = Tf.losses.sparse_softmax_cross_ Entropy (Labels=y_, logits=y_conv)
            cross_entropy = Tf.losses.softmax_cross_entropy (Onehot_labels=labels, logits =logits)
        cross_entropy_cost = Tf.reduce_mean (cross_entropy) return
        cross_entropy_cost

In the training model, you should control the number of iterations to avoid excessive fitting. When the number of iterations is 2000, there is a serious fit. An iteration number of 1000 would be a bit better. At the beginning, the printed cost value will float up and down, this is normal (at first I thought it was the model has a problem, and then know that it is normal) patiently waiting for the good. The training model will be stored in the hard disk, which can be read directly at the time of prediction.

    Def train (self, X_train, Y_train): Features = Tf.placeholder (Tf.float32, [None, $, 3]) labels = t  F.placeholder (Tf.int64, [None, 6]) logits, keep_prob, Train_mode = SELF.DEEPNN (features) cross_entropy = Self.cost (logits, labels) with Tf.name_scope (' Adam_optimizer '): Update_ops = Tf.get_collection (TF. Graphkeys.update_ops) with Tf.control_dependencies (update_ops): Train_step = Tf.train.AdamOpti Mizer (1e-4). Minimize (cross_entropy) graph_location = Tempfile.mkdtemp () print (' Saving graph to:%s '% GRA ph_location) Train_writer = Tf.summary.FileWriter (graph_location) train_writer.add_graph (tf.get_default_gr APh ()) mini_batches = Random_mini_batches (X_train, Y_train, mini_batch_size=32, seed=none) saver = tf.tr Ain. Saver () with TF.
           Session () as Sess:sess.run (Tf.global_variables_initializer ()) to I in range (1000):     X_mini_batch, Y_mini_batch = Mini_batches[np.random.randint (0, Len (mini_batches))] Train_step.run (fee
                    D_dict={features:x_mini_batch, Labels:y_mini_batch, keep_prob:0.5, train_mode:true}) if I% 20 = 0:
                                          Train_cost = Sess.run (cross_entropy, Feed_dict={features:x_mini_batch, Labels:y_mini_batch, keep_prob:1.0, train_mode:false}) print (' Step%d, training cost%g '% (i, train_cost)) Saver.save (Sess, Self.model_save_path)

Model prediction. First initialize graph and then read the model parameter data in the hard disk.

    def evaluate (self, test_features, test_labels, name= ' test '):
        tf.reset_default_graph ()

        x = Tf.placeholder ( Tf.float32, [None, $, 3])
        Y_ = Tf.placeholder (Tf.int64, [None, 6])

        logits, keep_prob, Train_mode = SELF.DEEPN N (x)
        accuracy = self.accuracy (logits, y_)

        saver = Tf.train.Saver () with
        TF. Session () as Sess:
            saver.restore (Sess, self.model_save_path)
            accu = sess.run (accuracy, feed_dict={x:test_ Features, Y_: test_labels,keep_prob:1.0, train_mode:false})
            print ('%s accuracy '% (name,%g))

The results of this test, the number of iterations is 2000 times, there is a serious fit. It would be much better to tune the number of iterations to 1000.

The idea of this article comes from Wunda's course on the depth study of lesson four.

DataSet Download: https://pan.baidu.com/s/1mj6Xj0c
Full source download: https://github.com/liangyihuai/my_tensorflow/tree/master/ Com/huai/converlution/resnets
Specific files See: hand_classifier_with_resnet.py

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.