我在Tensorflow中有一个预先训练的模型(完全训练过的imagenet预先训练的模型),带有resnet_50网络架构。现在,我正在使用Foolbox来获取预测。
但是模型在原始图像上返回了错误的预测(模型为1.0准确)。
您能帮我解决问题吗?
import tensorflow as tf
import resnet50ORL
import numpy as np
import foolbox
import scipy.io as sio
def convert_to_one_hot(Y, C):
Y = np.eye(C)[Y.reshape(-1)].T
return Y
DATA = sio.loadmat('/home/vision/Data/DSCN_data/ORL_32x32.mat')
X_train = DATA['fea'].reshape(400, 32, 32, 1)/255
x1 = X_train[0, :, :, :] #.reshape(32, 32, 1)
Y_train = DATA['gnd']
Y_train = convert_to_one_hot(Y_train-1, 40).T
m, H_size, W_size, C_size = X_train.shape
classes = 40
X = tf.placeholder(tf.float32, shape=(None, H_size, W_size, C_size), name='X')
Y = tf.placeholder(tf.float32, shape=(None, classes), name='Y')
logits = resnet50ORL.ResNet50_reference(X, classes)
accuracy = tf.reduce_mean(tf.cast(tf.equal(tf.argmax(logits, axis=1),
tf.argmax(Y, axis=1)), tf.float32))
saver = tf.train.Saver(tf.trainable_variables())
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
sess.run(tf.local_variables_initializer())
saver.restore(sess, '/home/vision/Data/checkpoint/ORL0/ORL.ckpt-541')
model = foolbox.models.TensorFlowModel(X, logits, (0, 1), channel_axis=1)
print(np.argmax(model.predictions(x1)))
acc, bbb, ccc = sess.run([accuracy, logits, Y], feed_dict={X: X_train, Y: Y_train})
print(acc)
import tensorflow as tf
import scipy.io as sio
import numpy as np
import math
import os
os.environ["CUDA_VISIBLE_DEVICES"] = "0"
TRAINING = tf.Variable(initial_value=True, dtype=tf.bool, trainable=True)
def identity_block(X_input, kernel_size, filters, stage, block):
"""
Implementation of the identity block as defined in Figure 3
Arguments:
X -- input tensor of shape (m, n_H_prev, n_W_prev, n_C_prev)
kernel_size -- integer, specifying the shape of the middle CONV's window for the main path
filters -- python list of integers, defining the number of filters in the CONV layers of the main path
stage -- integer, used to name the layers, depending on their position in the network
block -- string/character, used to name the layers, depending on their position in the network
Returns:
X -- output of the identity block, tensor of shape (n_H, n_W, n_C)
"""
# defining name basis
conv_name_base = 'res' + str(stage) + block + '_branch'
bn_name_base = 'bn' + str(stage) + block + '_branch'
with tf.name_scope("id_block_stage"+str(stage)):
filter1, filter2, filter3 = filters
X_shortcut = X_input
# First component of main path
x = tf.layers.conv2d(X_input, filter1, kernel_size=(1, 1), strides=(1, 1), name=conv_name_base+'2a')
x = tf.layers.batch_normalization(x, axis=3, name=bn_name_base+'2a', training=TRAINING)
x = tf.nn.relu(x)
# Second component of main path
x = tf.layers.conv2d(x, filter2, (kernel_size, kernel_size), padding='same', name=conv_name_base+'2b')
# batch_norm2 = tf.layers.batch_normalization(conv2, axis=3, name=bn_name_base+'2b', training=TRAINING)
x = tf.nn.relu(x)
# Third component of main path
x = tf.layers.conv2d(x, filter3, kernel_size=(1, 1), name=conv_name_base+'2c')
x = tf.layers.batch_normalization(x, axis=3, name=bn_name_base + '2c', training=TRAINING)
# Final step: Add shortcut value to main path, and pass it through a RELU activation
X_add_shortcut = tf.add(x, X_shortcut)
add_result = tf.nn.relu(X_add_shortcut)
return add_result
def convolutional_block(X_input, kernel_size, filters, stage, block, stride = 2):
"""
Implementation of the convolutional block as defined in Figure 4
Arguments:
X -- input tensor of shape (m, n_H_prev, n_W_prev, n_C_prev)
kernel_size -- integer, specifying the shape of the middle CONV's window for the main path
filters -- python list of integers, defining the number of filters in the CONV layers of the main path
stage -- integer, used to name the layers, depending on their position in the network
block -- string/character, used to name the layers, depending on their position in the network
stride -- Integer, specifying the stride to be used
Returns:
X -- output of the convolutional block, tensor of shape (n_H, n_W, n_C)
"""
# defining name basis
conv_name_base = 'res' + str(stage) + block + '_branch'
bn_name_base = 'bn' + str(stage) + block + '_branch'
with tf.name_scope("conv_block_stage" + str(stage)):
# Retrieve Filters
filter1, filter2, filter3 = filters
# Save the input value
X_shortcut = X_input
# First component of main path
x = tf.layers.conv2d(X_input, filter1, kernel_size=(1, 1), strides=(stride, stride), name=conv_name_base+'2a')
x = tf.layers.batch_normalization(x, axis=3, name=bn_name_base+'2a', training=TRAINING)
x = tf.nn.relu(x)
# Second component of main path
x = tf.layers.conv2d(x, filter2, (kernel_size, kernel_size), padding='same', name=conv_name_base + '2b')
x = tf.layers.batch_normalization(x, axis=3, name=bn_name_base + '2b', training=TRAINING)
x = tf.nn.relu(x)
# Third component of main path
x = tf.layers.conv2d(x, filter3, (1, 1), name=conv_name_base + '2c')
x = tf.layers.batch_normalization(x, axis=3, name=bn_name_base + '2c', training=TRAINING)
# SHORTCUT PATH
X_shortcut = tf.layers.conv2d(X_shortcut, filter3, (1, 1), strides=(stride, stride), name=conv_name_base + '1')
X_shortcut = tf.layers.batch_normalization(X_shortcut, axis=3, name=bn_name_base + '1', training=TRAINING)
# Final step: Add shortcut value to main path, and pass it through a RELU activation
X_add_shortcut = tf.add(X_shortcut, x)
add_result = tf.nn.relu(X_add_shortcut)
return add_result
def ResNet50_reference(X, classes= 6):
"""
Implementation of the popular ResNet50 the following architecture:
CONV2D -> BATCHNORM -> RELU -> MAXPOOL -> CONVBLOCK -> IDBLOCK*2 -> CONVBLOCK -> IDBLOCK*3
-> CONVBLOCK -> IDBLOCK*5 -> CONVBLOCK -> IDBLOCK*2 -> AVGPOOL -> TOPLAYER
Arguments:
Returns:
"""
x = tf.pad(X, tf.constant([[0, 0], [3, 3], [3, 3], [0, 0]]), "CONSTANT")
# stage 1
x = tf.layers.conv2d(x, filters=64, kernel_size=(3, 3), strides=(1, 1), padding='same', name='conv1')
x = tf.layers.batch_normalization(x, axis=3, name='bn_conv1')
x = tf.nn.relu(x)
# x = tf.layers.max_pooling2d(x, pool_size=(3, 3), strides=(2, 2))
# stage 2
x = convolutional_block(x, kernel_size=3, filters=[64, 64, 256], stage=2, block='a', stride=1)
x = identity_block(x, 3, [64, 64, 256], stage=2, block='b')
x = identity_block(x, 3, [64, 64, 256], stage=2, block='c')
# stage 3
x = convolutional_block(x, kernel_size=3, filters=[128, 128, 512], stage=3, block='a', stride=2)
x = identity_block(x, 3, [128, 128, 512], stage=3, block='b')
x = identity_block(x, 3, [128, 128, 512], stage=3, block='c')
x = identity_block(x, 3, [128, 128, 512], stage=3, block='d')
# stage 4
x = convolutional_block(x, kernel_size=3, filters=[256, 256, 1024], stage=4, block='a', stride=2)
x = identity_block(x, 3, [256, 256, 1024], stage=4, block='b')
x = identity_block(x, 3, [256, 256, 1024], stage=4, block='c')
x = identity_block(x, 3, [256, 256, 1024], stage=4, block='d')
x = identity_block(x, 3, [256, 256, 1024], stage=4, block='e')
x = identity_block(x, 3, [256, 256, 1024], stage=4, block='f')
# stage 5
x = convolutional_block(x, kernel_size=3, filters=[512, 512, 2048], stage=5, block='a', stride=2)
x = identity_block(x, 3, [512, 512, 2048], stage=5, block='b')
x = identity_block(x, 3, [512, 512, 2048], stage=5, block='c')
x = tf.layers.average_pooling2d(x, pool_size=(2, 2), strides=(1, 1))
flatten = tf.layers.flatten(x, name='flatten')
logits = tf.layers.dense(flatten, units=40)
# dense1 = tf.layers.dense(flatten, units=50, activation=tf.nn.relu)
# logits = tf.layers.dense(dense1, units=10, activation=tf.nn.softmax)
return logits
def random_mini_batches(X, Y, mini_batch_size=64, seed=None):
"""
Creates a list of random minibatches from (X, Y)
Arguments:
X -- input data, of shape (input size, number of examples) (m, Hi, Wi, Ci)
Y -- true "label" vector (containing 0 if cat, 1 if non-cat), of shape (1, number of examples) (m, n_y)
mini_batch_size - size of the mini-batches, integer
seed -- this is only for the purpose of grading, so that you're "random minibatches are the same as ours.
Returns:
mini_batches -- list of synchronous (mini_batch_X, mini_batch_Y)
"""
m = X.shape[0] # number of training examples
mini_batches = []
np.random.seed(seed)
# Step 1: Shuffle (X, Y)
permutation = list(np.random.permutation(m))
shuffled_X = X[permutation, :, :, :]
shuffled_Y = Y[permutation, :]
# Step 2: Partition (shuffled_X, shuffled_Y). Minus the end case.
num_complete_minibatches = math.floor(
m / mini_batch_size) # number of mini batches of size mini_batch_size in your partitionning
for k in range(0, num_complete_minibatches):
mini_batch_X = shuffled_X[k * mini_batch_size: k * mini_batch_size + mini_batch_size, :, :, :]
mini_batch_Y = shuffled_Y[k * mini_batch_size: k * mini_batch_size + mini_batch_size, :]
mini_batch = (mini_batch_X, mini_batch_Y)
mini_batches.append(mini_batch)
# Handling the end case (last mini-batch < mini_batch_size)
if m % mini_batch_size != 0:
mini_batch_X = shuffled_X[num_complete_minibatches * mini_batch_size: m, :, :, :]
mini_batch_Y = shuffled_Y[num_complete_minibatches * mini_batch_size: m, :]
mini_batch = (mini_batch_X, mini_batch_Y)
mini_batches.append(mini_batch)
return mini_batches
def convert_to_one_hot(Y, C):
Y = np.eye(C)[Y.reshape(-1)].T
return Y
def main():
global TRAINING
DATA = sio.loadmat('/home/vision/Data/DSCN_data/ORL_32x32.mat')
X_train = DATA['fea'].reshape(400, 32, 32, 1)/255
Y_train = DATA['gnd']
Y_train = convert_to_one_hot(Y_train-1, 40).T
m, H_size, W_size, C_size = X_train.shape
classes = 40
mini_batch_size = 20
max_step = 20000
best_acc = 0
global_step = tf.Variable(0, trainable=False)
model_name = 'ORL'
restore_path = '/home/vision/Data/checkpoint/' + model_name
if not os.path.isdir(restore_path):
os.makedirs(restore_path)
path = restore_path + '/' + model_name + '.ckpt'
X = tf.placeholder(tf.float32, shape=(None, H_size, W_size, C_size), name='X')
Y = tf.placeholder(tf.float32, shape=(None, classes), name='Y')
logits = ResNet50_reference(X)
loss = tf.reduce_mean(tf.losses.softmax_cross_entropy(onehot_labels=Y, logits=logits))
# optimizer = tf.train.GradientDescentOptimizer(0.001)
# optimizer = tf.train.MomentumOptimizer(0.1, momentum=0.9, use_locking=False, name='Momentum')
update_ops = tf.get_collection(tf.GraphKeys.UPDATE_OPS)
with tf.control_dependencies(update_ops):
train_op = tf.train.AdamOptimizer(1e-3).minimize(loss, global_step=global_step)
saver = tf.train.Saver() # 位置要放对,否则参数无法save
accuracy = tf.reduce_mean(tf.cast(tf.equal(tf.argmax(logits, axis=1), tf.argmax(Y, axis=1)), tf.float32))
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
sess.run(tf.local_variables_initializer())
mini_batches = random_mini_batches(X_train, Y_train, mini_batch_size)
ckpt = tf.train.get_checkpoint_state(restore_path)
if ckpt and ckpt.model_checkpoint_path:
saver.restore(sess, ckpt.model_checkpoint_path)
step = int(os.path.basename(ckpt.model_checkpoint_path).split('-')[1])
print('model restored: ', 'pretraining step =', step)
else:
step = 0
while step < max_step:
X_mini_batch, Y_mini_batch = mini_batches[np.random.randint(0, len(mini_batches))]
_, cost_sess = sess.run([train_op, loss], feed_dict={X: X_mini_batch, Y: Y_mini_batch})
acc = sess.run(accuracy, feed_dict={X: X_train, Y: Y_train})
if step % 50 == 0:
print('step:', step, '|', cost_sess)
if acc > best_acc:
print('step:', step, '|', 'Saving...', 'acurracy: ', acc)
saver.save(sess, path, global_step=global_step)
best_acc = acc
step = step + 1
sess.run(tf.assign(TRAINING, False))
if __name__ == '__main__':
main()