1. 程式人生 > >tensorflow.contrib.slim實現vgg19和resnet101兩種基礎網路

tensorflow.contrib.slim實現vgg19和resnet101兩種基礎網路

最近自己按照網上的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')