分别使用tensorflow2.0版本与tensorflow1.13版本构建Squeezenet网络

SqueezeNet的网络结构就不在这里详细介绍,这里给出用tensorflow1.x版本和tensorflow2.x版本的代码实现。

首先给出tensorflow1.x版本的代码实现

# coding=utf-8
import tensorflow as tf
import numpy as np
import cv2
import pickle

POOLING_LAYERS = [1, 3, 5]
MODEL_PATH = 'data/squeeze_net/model.pkl'

class SqueezeNet(object):

  def __init__(self, imgs):
    self.imgs = tf.placeholder(tf.float32, [None, 224, 224, 3])
    self.imgs = imgs
    self.weights = {}
    self.net = {}
    self.build_model()

  # take  BGR 0~255 image, i.e. like the ones loaded by open CV
  def build_model(self):
    net = {}
    self.net = net
    self.model = pickle.load(open(MODEL_PATH, 'rb'),encoding='iso-8859-1')
    for k in self.model.keys():
      print(k, self.model[k].shape)
    # Caffe order is BGR, this model is RGB.
    # The mean values are from caffe protofile from DeepScale/SqueezeNet github repo.
    # self.mean = tf.constant([123.0, 117.0, 104.0],
    #                         dtype=tf.float32, shape=[1, 1, 1, 3], name='img_mean')
    self.mean = tf.constant(
        [104.0, 117.0, 123.0],
        dtype=tf.float32,
        shape=[1, 1, 1, 3],
        name='img_mean')
    images = self.imgs - self.mean
    # images = self.imgs-np.array([123.0, 117.0, 104.0]).reshape([1,1,1,3])
    # images = self.imgs-self.imgs

    # images = tf.transpose(images, [0,2,1,3])
    #net是一个字典
    net['input'] = images
    # conv1_1
    net['conv1'] = self.conv_layer(
        'conv1',
        net['input'],
        W=self.weight_variable(
            [3, 3, 3, 64],
            name='conv1_w',
            init=np.transpose(self.model['conv1_weights'], [2, 3, 1, 0])),
        stride=[1, 2, 2, 1],
        padding='VALID') + self.model['conv1_bias'][None, None, None, :]

    net['relu1'] = self.relu_layer(
        'relu1', net['conv1'], b=self.bias_variable([64], 'relu1_b', value=0.0))
    net['pool1'] = self.pool_layer('pool1', net['relu1'])

    net['fire2'] = self.fire_module('fire2', net['pool1'], 16, 64, 64)
    net['fire3'] = self.fire_module('fire3', net['fire2'], 16, 64, 64)
    net['pool3'] = self.pool_layer('pool3', net['fire3'], padding='SAME')

    net['fire4'] = self.fire_module('fire4', net['pool3'], 32, 128, 128)
    net['fire5'] = self.fire_module('fire5', net['fire4'], 32, 128, 128)
    net['pool5'] = self.pool_layer('pool5', net['fire5'], padding='SAME')

    net['fire6'] = self.fire_module('fire6', net['pool5'], 48, 192, 192)
    net['fire7'] = self.fire_module('fire7', net['fire6'], 48, 192, 192)
    net['fire8'] = self.fire_module('fire8', net['fire7'], 64, 256, 256)
    net['pool8'] = self.pool_layer('pool8', net['fire8'])
    net['fire9'] = self.fire_module('fire9', net['fire8'], 64, 256, 256)
    print(net['fire9'].shape)

    # 50% dropout removed
    #net['dropout9'] = tf.nn.dropout(net['fire9'], self.dropout)
    net['conv10'] = self.conv_layer(
        'conv10',
        net['fire9'],
        W=self.weight_variable(
            [1, 1, 512, 1000],
            name='conv10',
            init=np.transpose(self.model['conv10_weights'], [2, 3, 1, 0])),
        padding='VALID') + self.model['conv10_bias'][None, None, None, :]
    print(net['conv10'].shape)
    net['relu10'] = self.relu_layer(
        'relu10',
        net['conv10'],
        b=self.bias_variable([1000], 'relu10_b', value=0.0))
    print(net['relu10'].shape)
    net['pool10'] = self.pool_layer('pool10', net['relu10'], pooling_type='avg')
    print(net['pool10'].shape)
    avg_pool_shape = tf.shape(net['pool10'])

    net['pool_reshaped'] = tf.reshape(net['pool10'], [avg_pool_shape[0], -1])
    self.fc2 = net['pool_reshaped']
    self.logits = net['pool_reshaped']

    self.probs = tf.nn.softmax(self.logits)
    self.net = net

  def bias_variable(self, shape, name, value=0.1, from_caffe=False):
    if not from_caffe:
      self.weights[name] = tf.get_variable(
          'bias_' + name,
          initializer=tf.constant_initializer(value),
          shape=shape)
    else:
      self.weights[name] = tf.get_variable(
          'bias_' + name,
          initializer=tf.constant_initializer(value=value),
          shape=shape)
    return self.weights[name]

  def weight_variable(self, shape, name=None, init='xavier'):
    if init == 'variance':
      assert False
      initial = tf.get_variable(
          'W' + name,
          shape,
          initializer=tf.contrib.layers.variance_scaling_initializer())
    elif init == 'xavier':
      assert False
      initial = tf.get_variable(
          'W' + name, shape, initializer=tf.contrib.layers.xavier_initializer())
    else:
      assert isinstance(init, np.ndarray)
      print(name, init.shape)
      initial = tf.get_variable(
          'W' + name, shape, initializer=tf.constant_initializer(value=init))

    self.weights[name] = initial
    return self.weights[name]

  def relu_layer(self, layer_name, layer_input, b=None):
    if b:
      layer_input += b
    relu = tf.nn.relu(layer_input)
    return relu

  def pool_layer(self,
                 layer_name,
                 layer_input,
                 pooling_type='max',
                 padding='VALID'):
    if pooling_type == 'avg':
      pool = tf.nn.avg_pool(
          layer_input,
          ksize=[1, 14, 14, 1],
          strides=[1, 1, 1, 1],
          padding=padding)
    elif pooling_type == 'max':
      pool = tf.nn.max_pool(
          layer_input,
          ksize=[1, 3, 3, 1],
          strides=[1, 2, 2, 1],
          padding=padding)
    return pool

  def conv_layer(self,
                 layer_name,
                 layer_input,
                 W,
                 stride=[1, 1, 1, 1],
                 padding='VALID'):
    return tf.nn.conv2d(layer_input, W, strides=stride, padding=padding)

  def fire_module(self,
                  layer_name,
                  layer_input,
                  s1x1,
                  e1x1,
                  e3x3,
                  residual=False):
    """ Fire module consists of squeeze and expand convolutional layers. """
    fire = {}

    shape = layer_input.get_shape()

    # squeeze np.transpose(self.model['conv1_weights'], [2,3,1,0])),
    s1_weight = self.weight_variable(
        [1, 1, int(shape[3]), s1x1], layer_name + '_s1_weight',
        np.transpose(
            self.model[layer_name + '/' + 'squeeze1x1_weights'],
            axes=[2, 3, 1, 0]))

    # expand
    e1_weight = self.weight_variable(
        [1, 1, s1x1, e1x1], layer_name + '_e1',
        np.transpose(
            self.model[layer_name + '/' + 'expand1x1_weights'],
            axes=[2, 3, 1, 0]))
    e3_weight = self.weight_variable(
        [3, 3, s1x1, e3x3], layer_name + '_e3',
        np.transpose(
            self.model[layer_name + '/' + 'expand3x3_weights'],
            axes=[2, 3, 1, 0]))

    fire['s1'] = self.conv_layer(
        layer_name + '_s1', layer_input, W=s1_weight, padding='SAME')
    fire['relu1'] = self.relu_layer(
        layer_name + '_relu1',
        fire['s1'],
        b=self.bias_variable([s1x1], layer_name + '_fire_bias_s1'))

    fire['e1'] = self.conv_layer(
        layer_name + '_e1', fire['relu1'], W=e1_weight,
        padding='SAME')  # 'SAME' and 'VALID' padding should be the same here
    fire['e3'] = self.conv_layer(
        layer_name + '_e3', fire['relu1'], W=e3_weight, padding='SAME')
    fire['concat'] = tf.concat([
        tf.add(fire['e1'],
               self.bias_variable(
                   [e1x1],
                   name=layer_name + '_fire_bias_e1',
                   value=self.model[layer_name + '/' + 'expand1x1_bias'])),
        tf.add(fire['e3'],
               self.bias_variable(
                   [e3x3],
                   name=layer_name + '_fire_bias_e3',
                   value=self.model[layer_name + '/' + 'expand3x3_bias']))
    ], 3)

    if residual:
      fire['relu2'] = self.relu_layer(layer_name + 'relu2_res',
                                      tf.add(fire['concat'], layer_input))
    else:
      fire['relu2'] = self.relu_layer(layer_name + '_relu2', fire['concat'])
    self.net[layer_name + '_debug'] = fire['relu2']
    return fire['relu2']

  def get_features_out(self):
    return self.net['pool8']


z = tf.random.normal([16,224,224,3])
s = Squeezenet()
print(s(z).shape)

 

接下来给出tensorflow2.x版本的代码实现

import tensorflow as tf
import numpy as np
import random


class Fire(tf.keras.Model):
    def __init__(self,filters_1,filters_2):
        super().__init__()
        self.squeeze = tf.keras.layers.Conv2D(filters = filters_1,kernel_size = 1,strides = 1,padding='SAME',activation=tf.nn.relu)
        self.expand_1 = tf.keras.layers.Conv2D(filters = filters_2,kernel_size = 1,strides = 1,padding='SAME',activation=tf.nn.relu)
        self.expand_3 = tf.keras.layers.Conv2D(filters = filters_2,kernel_size = 3,strides = 1,padding='SAME',activation=tf.nn.relu)

    def call(self,inputs):
        x = self.squeeze(inputs)
        x1 = self.expand_1(x)
        x2 = self.expand_3(x)

        return tf.concat([x1, x2], axis=3)


class Squeezenet(tf.keras.Model):
    def __init__(self):
        super().__init__()
        self.conv1 = tf.keras.layers.Conv2D(filters=96, kernel_size=7, strides=2, padding='SAME', activation=tf.nn.relu)
        self.pool1 = tf.keras.layers.MaxPool2D(pool_size=3, strides=2)
        self.conv2 = tf.keras.layers.Conv2D(filters=1000, kernel_size=1, strides=1, padding='SAME',activation=tf.nn.relu)
        self.pool2 = tf.keras.layers.AveragePooling2D(pool_size=13, strides=1)
        self.flatten = tf.keras.layers.Flatten()
        self.fc1 = tf.keras.layers.Dense(10, activation=tf.nn.softmax)
    def call(self,inputs):
        print(inputs.shape)
        x = self.conv1(inputs)
        print(x.shape)
        fir1 = Fire(16,64)
        x = fir1(x)
        print(x.shape)
        fir2 = Fire(16,64)
        x1 = fir2(x)
        fir3 = Fire(32,128)
        x = fir3(x1)
        x = self.pool1(x)
        fir4 = Fire(32,128)
        x = fir4(x)
        fire5 = Fire(48,192)
        x = fire5(x)
        fir6 = Fire(48,192)
        x = fir6(x)
        fir7 = Fire(64,256)
        x = fir7(x)
        x = self.pool1(x)
        fir8 = Fire(64,256)
        x = fir8(x)
        x = self.conv2(x)
        x = self.pool2(x)
        x = self.flatten(x)
        out = self.fc1(x)
        return out

z = tf.random.normal([16,224,224,3])
s = Squeezenet()
print(s(z).shape)

 

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

杨小嗨yang

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值