tensorflow.contrib.slim實現vgg19和resnet101兩種基礎網路
阿新 • • 發佈:2019-01-08
最近自己按照網上的tensorflow中slim的編寫流程,根據兩篇部落格和的模板自己將resnet101和vgg19實現了一遍,感覺受益匪淺,使用slim實現基礎網路比使用tf.nn快捷和便利的多,以後還得向大佬學習。
vgg19程式碼
# --*-- coding:utf8 --*-- import tensorflow as tf import tensorflow.contrib.slim as slim import random import os os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2' def vgg16(inputs): with slim.arg_scope([slim.conv2d, slim.fully_connected], activation_fn=tf.nn.relu, weights_initializer=tf.truncated_normal_initializer(0.0, 0.01), weights_regularizer=slim.l2_regularizer(0.0005)): net = slim.repeat(inputs, 2, slim.conv2d, 64, [3, 3], scope='conv1') net = slim.max_pool2d(net, [2, 2], scope='pool1') net = slim.repeat(net, 2, slim.conv2d, 128, [3, 3], scope='conv2') net = slim.max_pool2d(net, [2, 2], scope='pool2') net = slim.repeat(net, 4, slim.conv2d, 256, [3, 3], scope='conv3') net = slim.max_pool2d(net, [2, 2], scope='pool3') net = slim.repeat(net, 4, slim.conv2d, 512, [3, 3], scope='conv4') net = slim.max_pool2d(net, [2, 2], scope='pool4') net = slim.repeat(net, 4, slim.conv2d, 512, [3, 3], scope='conv5') net = slim.max_pool2d(net, [2, 2], scope='pool5') net = slim.flatten(net, scope='flat') net = slim.fully_connected(net, 4096, scope='fc1') net = slim.dropout(net, keep_prob=0.5, scope='dropt1') net = slim.fully_connected(net, 4096, scope='fc2') net = slim.dropout(net, keep_prob=0.5, scope='dropt2') net = slim.fully_connected(net, 1000, scope='fc3') net = slim.softmax(net, scope='net') return net img_size = 224 data_sum = 100 output_num = 1000 batch = 10 x = tf.placeholder('float', [batch , img_size, img_size, 3]) y_ = tf.placeholder('float', [None, 1000]) y = vgg16(x) cross_entropy = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(labels=y_, logits=y)) regularization = tf.add_n(tf.losses.get_regularization_losses()) train_step = tf.train.AdamOptimizer(1e-4).minimize(cross_entropy+regularization) correction = tf.equal(tf.argmax(y, 1), tf.argmax(y_, 1)) accuracy = tf.reduce_mean(tf.cast(correction, 'float')) session = tf.InteractiveSession() session.run(tf.global_variables_initializer()) data = tf.random_normal([data_sum, img_size, img_size, 3]).eval() label = tf.zeros([data_sum, output_num]).eval() for i in range(data_sum): label[i][random.randint(0, output_num-1)] = 1 for i in range(200): batchx = data[(i*batch)%data_sum:(i*batch)%data_sum+batch] batchy = label[(i*batch)%data_sum:(i*batch)%data_sum+batch] session.run(train_step, feed_dict={x:batchx, y_:batchy}) if i%10 == 0: loss = session.run(cross_entropy, feed_dict={x:batchx, y_:batchy}) acc = session.run(accuracy, feed_dict={x:batchx, y_:batchy}) print(i, 'loss is %f, accuracy is %f' % (loss, acc))
resnet101程式碼:
# --*-- coding:utf8 --*-- from __future__ import division import os os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2' import tensorflow as tf import collections import tensorflow.contrib.slim as slim class Block(collections.namedtuple('Block', ['scope', 'unit_fn', 'args'])): 'A Block express base unit of Resnet' @slim.add_arg_scope def stack_blocks_dense(net, blocks, outputs_collections=None): for block in blocks: with tf.variable_scope(block.scope, 'block', [net]) as sc: for i, unit in enumerate(block.args): with tf.variable_scope('unit_%d' % (i+1), values=[net]): unit_depth, unit_bottleneck_depth, stride = unit net = block.unit_fn(net, unit_depth, unit_bottleneck_depth, stride) net = slim.utils.collect_named_outputs(outputs_collections, 'block', net) return net @slim.add_arg_scope def resnet_arg_scope(is_training=True, weight_decay=0.0001, batch_norm_decay=0.997, batch_norm_epsilon=1e-5, batch_norm_scale=True): batch_norm_params = { 'is_training': is_training, 'decay': batch_norm_decay, 'epsilon': batch_norm_epsilon, 'scale': batch_norm_scale, 'updates_collections': tf.GraphKeys.UPDATE_OPS, } with slim.arg_scope( [slim.conv2d], weights_regularizer=slim.l2_regularizer(weight_decay), weights_initializer=slim.variance_scaling_initializer(), activation_fn=tf.nn.relu, normalizer_fn=slim.batch_norm, normalizer_params=batch_norm_params): with slim.arg_scope([slim.batch_norm], **batch_norm_params): with slim.arg_scope([slim.max_pool2d], padding='SAME') as arg_sc: return arg_sc @slim.add_arg_scope def bottleneck(inputs, unit_depth, unit_bottleneck_depth, stride, outputs_collections=None, scope=None): with tf.variable_scope(scope, 'resnet_v2', [inputs]) as sc: depth_in = slim.utils.last_dimension(inputs.get_shape(), min_rank = 4) preact = slim.batch_norm(inputs, activation_fn=tf.nn.relu, scope='preact') if depth_in == unit_depth: shortcut = slim.max_pool2d(inputs, [1, 1], stride=stride, scope='shortcut') else: shortcut = slim.conv2d(preact, unit_depth, [1, 1], stride=stride, normalizer_fn=None, activation_fn=None, scope='shortcut') net = slim.conv2d(preact, unit_bottleneck_depth, [1, 1], stride=1, scope='conv1') net = slim.conv2d(net, unit_bottleneck_depth, [3, 3], stride=1, padding='SAME', scope='conv2') net = slim.conv2d(net, unit_depth, [1, 1], stride=stride, normalizer_fn=None, activation_fn=None, scope='conv3') res = shortcut + net return slim.utils.collect_named_outputs(outputs_collections, sc.name, res) def resnet_v2(inputs, blocks, num_classes=None, global_pooling=True, include_root_block=True, reuse=None, scope=None): with tf.variable_scope(scope, 'resnet_v2', [inputs], reuse=reuse) as sc: end_points_collection = sc.original_name_scope + 'end_points' with slim.arg_scope([slim.conv2d, stack_blocks_dense, bottleneck], outputs_collections=end_points_collection): net = inputs if include_root_block: net = slim.conv2d(net, 64, [7, 7], stride=2, padding='SAME', scope='conv1') net = slim.max_pool2d(net, [3, 3], stride=2, scope='pool1') net = stack_blocks_dense(net, blocks) net = slim.batch_norm(net, activation_fn=tf.nn.relu, scope='postnorm') if global_pooling: net = tf.reduce_mean(net, [1, 2], name='pool5', keep_dims=True) if num_classes is not None: net = slim.conv2d(net, num_classes, [1, 1], activation_fn=None, normalizer_fn=None, scope='logits') end_points = slim.utils.convert_collection_to_dict(end_points_collection) if num_classes is not None: end_points['predictions'] = slim.softmax(net, scope='predictions') return net, end_points def resnet_v2_101(inputs, num_classes=None, global_pooling=True, reuse=None, scope='resnet_v2_101'): blocks = [ Block('block1', bottleneck, [(256, 64, 1)]*2 + [(256, 64, 2)]), Block('block2', bottleneck, [(512, 128, 1)] * 3 + [(512, 128, 2)]), Block('block3', bottleneck, [(1024, 256, 1)] * 22 + [(1024, 256, 2)]), Block('block4', bottleneck, [(2048, 512, 1)] * 3) ] return resnet_v2(inputs, blocks, num_classes, global_pooling, include_root_block=True, reuse=reuse, scope=scope) from datetime import datetime import math import time def time_tensorflow_run(session, saver, save_file, target, info_string): num_total = 100 num_step = 10 for i in range(num_total): startime = time.time() session.run(target) duration = time.time() - startime if i%num_step == 0: print('%s: step %d, duration = %.3f' % (datetime.now(), i, duration)) saver.save(session, save_file) save_file = '/home/hley/data/model/train_model.ckpt1' batch = 32 length, width = 224, 224 inputData = tf.random_uniform((batch, length, width, 3)) with slim.arg_scope(resnet_arg_scope(is_training=False)): net, end_points = resnet_v2_101(inputData, num_classes=1000) session = tf.InteractiveSession() session.run(tf.global_variables_initializer()) saver = tf.train.Saver() time_tensorflow_run(session, saver, save_file, net, 'Forward')