首页 新闻 搜索 专区 学院

请问是否可以将Alexnet改成fcn,下面代码是否正确。我跑出来感觉精度一直很低。本人小白,请各位大神帮忙解答一下。非常感谢。

0
悬赏园豆:60 [待解决问题]

本人想将alexnet的最后的全连接层改成卷积层,实现fcn,训练模型,然后再图像金字塔来实现不同大小图片的人脸识别(因为fcn的话,输入的大小可以不固定)。请问这种理解知否正确,实现是否可行。下面的代码是否改的正确。或者该怎么改呀?卡住好几天了。谢谢。

import tensorflow as tf
import numpy as np
import cv2 as cv

learning_rate = 0.001
num_epochs = 10
dropout_rate = 0.75
IMAGE_SIZE = 227
BATCH_SIZE = 64

class AlexNet(object):
def init(self, x, keep_prob, learning_rate, image_size=IMAGE_SIZE):
self.x = x
self.keep_prob = keep_prob
self.num_class = num_class
self.learning_rate = learning_rate
self.image_size = image_size
self.train_index = 1 # 记录读取的文本文件中的行数,一个33000张图片左右,将每一张图片的路径和label值(0, 1)放在一行
self.build_AlexNet()

def build_AlexNet(self):

    # 1st layer:conv ->lrn->pool
    conv1 = convolution_layer(self.x, 96, 11, 11, 4, 4, name='conv1', groups=2, padding='VALID')
    conv1 = tf.nn.relu(conv1)
    norm1 = lrn_layer(conv1, 2, 1e-4, 0.75, name='norm1')
    pool1 = max_pool_layer(norm1, 3, 3, 2, 2, name='pool1', padding='VALID')

    # 2st layer: conv
    conv2 = convolution_layer(pool1, 256, 5, 5, 1, 1, name='conv2', groups=2)
    conv2 = tf.nn.relu(conv2)
    norm2 = lrn_layer(conv2, 2, 1e-4, 0.75, name='norm2')
    pool2 = max_pool_layer(norm2, 3, 3, 2, 2, name='pool2', padding='VALID')

    # 3rd layer conv
    conv3 = convolution_layer(pool2, 384, 3, 3, 1, 1, name='conv3')
    conv3 = tf.nn.relu(conv3)

    # 4th layer: conv
    conv4 = convolution_layer(conv3, 384, 3, 3, 1, 1, name='conv4', groups=2)
    conv4 = tf.nn.relu(conv4)

    # 5th layer: conv->pool
    conv5 = convolution_layer(conv4, 256, 3, 3, 1, 1, name='conv5', groups=2,  padding='VALID')
    conv5 = tf.nn.relu(conv5)
    pool5 = max_pool_layer(conv5, 3, 3, 2, 2, name='pool5')

    # 6th layer : fcnn
    fcn6 = convolution_layer(pool5, 4096, 6, 6, 1, 1, name='fcn6', groups=1, padding='VALID')
    fcn6 = tf.nn.relu(fcn6)
    dropout6 = dropout(fcn6, self.keep_prob)

    # 7th layer: fcn
    fcn7 = convolution_layer(dropout6, 4096, 1, 1, 1, 1, name='fcn7', groups=1, padding='VALID')
    fcn7 = tf.nn.relu(fcn7)
    dropout7 = dropout(fcn7, self.keep_prob)

    # 8th layer: fc
    fc8 = convolution_layer(dropout7, 2, 1, 1, 1, 1, name='fc8', padding='VALID')
    self.pred = tf.nn.sigmoid(tf.reshape(fc8, shape=[-1, 2]))

def get_per_image(self, train_val):
    if train_val == 'train':
        while True:
            line = linecache.getline(r"/path/train/train_shuffle.txt", self.train_index)
            self.train_index += 1
            img_name, label = line.split(' ', 2)
            img = cv.imread(img_name)
            pic = np.resize(img, [IMAGE_SIZE, IMAGE_SIZE, 3])
            return pic, label
    else:
        while True:
            line = linecache.getline(r"/path/val/val.txt", self.val_index)
            self.val_index += 1
            img_name, label = line.split(' ', 2)
            img = cv.imread(img_name)
            pic = np.resize(img, [IMAGE_SIZE, IMAGE_SIZE, 3])
            return pic, label

# 获取一个batch数量的样本数据和label
def get_batch_sample_data(self, train_val, batch_size=BATCH_SIZE):
    batch_x = np.zeros([batch_size, IMAGE_SIZE, IMAGE_SIZE, 3])
    batch_y = np.zeros([batch_size, 2])

    for i in range(batch_size):
        img, label = self.get_per_image(train_val)
        batch_x[i, :] = img
        if int(label) == 0:
            batch_y[i, :] = [1, 0]
        else:
            batch_y[i, :] = [0, 1]
    return batch_x, batch_y

def convolution_layer(x, filter_num, filter_height, filter_width, stride_x, stride_y, name, groups=1, padding='SAME'):
channel = int(x.get_shape()[-1])

conv2d = lambda a, b: tf.nn.conv2d(a, b, strides=[1, stride_y, stride_x, 1], padding=padding)

with tf.variable_scope(name, reuse=None):
    weights = tf.get_variable('weights', shape=[filter_height, filter_width, channel/groups, filter_num],
                              initializer=tf.contrib.layers.xavier_initializer_conv2d())
    biases = tf.get_variable('biases', shape=[filter_num], initializer=tf.constant_initializer(0.0))
    if groups == 1:
        conv = conv2d(x, weights)
    else:
        input_groups = tf.split(axis=3, num_or_size_splits=groups, value=x)
        weight_groups = tf.split(axis=3, num_or_size_splits=groups, value=weights)

        output_groups = [conv2d(a, b) for a, b in zip(input_groups, weight_groups)]
        conv = tf.concat(axis=3, values=output_groups)

    out = tf.nn.bias_add(name='out', value=conv, bias=biases)
    return out

def max_pool_layer(x, filter_height, filter_width, stride_y, stride_x, name, padding='SAME'):
"""

:param x:
:param filter_weight:
:param filter_width:
:param stride_y:
:param stride_x:
:param name:
:param padding:
:return:
"""

return tf.nn.max_pool(x, ksize=[1, filter_height, filter_width, 1], strides=[1, stride_y, stride_x, 1],
                      padding=padding, name=name)

def lrn_layer(x, radius, alpha, beta, name, bias=1.0):
"""

:param x:
:param radius:
:param alpha:
:param beta:
:param name:
:param bias:
:return:
"""
return tf.nn.local_response_normalization(x, depth_radius=radius, alpha=alpha, beta=beta, bias=bias, name=name)

def dropout(x, keep_prob):
"""

:param x:
:param keep_prob:
:return:
"""
return tf.nn.dropout(x, keep_prob)

def train_alexnet():
x = tf.placeholder(tf.float32, shape=[None, IMAGE_SIZE, IMAGE_SIZE, 3])
y = tf.placeholder(tf.float32, shape=[None, 2])
keep_prob = tf.placeholder(tf.float32)
global_step = tf.Variable(0, tf.int32)

net = AlexNet(x, keep_prob, learning_rate, IMAGE_SIZE)
outputs = net.pred
with tf.name_scope("train"):
    loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits=outputs, labels=y))
    optimizer = tf.train.AdamOptimizer(learning_rate).minimize(loss, global_step=global_step)
    max_idx_p = tf.argmax(outputs, axis=1)
    max_idx_l = tf.argmax(y, axis=1)
    correct_pred = tf.equal(max_idx_p, max_idx_l)
    acc = tf.reduce_mean(tf.cast(correct_pred, tf.float32))
    Saver = tf.train.Saver()
with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())

    step = 1
    for epoch in range(num_epochs):
        net.train_index = 1
        for i in range(500):
            batch_x, batch_y = net.get_batch_sample_data('train')
            _, loss_, acc_ = sess.run([optimizer, loss, acc],
                                      feed_dict={x: batch_x, y: batch_y, keep_prob: dropout_rate})
            print("acc")
            print(step, acc_)

            if acc_ > 0.95:
                Saver.save(sess, r"/path/train/model/alexnet", global_step=step)

            step += 1

if name == 'main':
train_alexnet()

指间的执着的主页 指间的执着 | 初学一级 | 园豆:142
提问于:2019-07-07 15:40
< >
分享
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册