注意inception_v3训练的图片的类型为(299,299,3),分类为1001,因此我们在进行预测前面需要将数据集转化为这种格式,见read_files.py文件;然后我们加载inception_v3网络以及其给定权值进行预测,见test.py文件,训练结果见底下图片所示:
read_files.py
#coding=utf-8
import tensorflow as tf
import numpy as np
import os
from PIL import Image
def to_categorial(y,n_classes):
y_std=np.zeros([len(y),n_classes])
for i in range(len(y)):
y_std[i,y[i]]=1.0
return y_std
def getFileArr(dir):
result_arr=[]
label_list=[]
map={}
map_file_result={}
map_file_label={}
map_new={}
count_label=0
count=0
file_list=os.listdir(dir)
for file in file_list:
file_path=os.path.join(dir,file)
label=file.split(".")[0].split("_")[0]
img=Image.open(file_path)
result=np.array([])
if(len(img.split())!=3):
map[file]="hahaha"
#os.remove(file_path)
else:
map[file]=label
if label not in label_list:
label_list.append(label)
map_new[label]=count_label
count_label=count_label+1
r,g,b=img.split()
r_arr=np.array(r).reshape(299*299)
g_arr=np.array(g).reshape(299*299)
b_arr=np.array(b).reshape(299*299)
img_arr=np.concatenate((r_arr,g_arr,b_arr))
result=np.concatenate((result,img_arr))
result=result.reshape((299,299,3))
map_file_result[file]=result
result_arr.append(result)
count=count+1
for file in file_list:
if map[file]!="hahaha":
map_file_label[file]=map_new[map[file]]
#map[file]=map_new[map[file]]
ret_arr=[]
for file in file_list:
if map[file]!="hahaha":
each_list=[]
label_one_zero=np.zeros(count_label)
result=map_file_result[file]
label=map_file_label[file]
#print(label_one_zero)
each_list.append(result)
each_list.append(label)
ret_arr.append(each_list)
np.save('test02_299.npy', ret_arr)
def load_data(train_dir,test_dir):
train_data=np.load(train_dir)
test_data=np.load(test_dir)
X_train_non,y_train_non=train_data[:,0],train_data[:,1]
X_test_non,y_test_non=test_data[:,0],test_data[:,1]
X_train=np.zeros([len(X_train_non),299,299,3])
X_test=np.zeros([len(X_test_non),299,299,3])
for i in range(len(X_train_non)):
X_train[i,:,:,:]=X_train_non[i]
for i in range(len(X_test_non)):
X_test[i,:,:,:]=X_test_non[i]
#y_train_non=y_train_non.tolist()
#y_test_non=y_test_non.tolist()
y_train=to_categorial(y_train_non,1001)
y_test=to_categorial(y_test_non,1001)
return (X_train,y_train),(X_test,y_test)
def load_data(test_dir):
test_data=np.load(test_dir)
X_test_non,y_test_non=test_data[:,0],test_data[:,1]
X_test=np.zeros([len(X_test_non),299,299,3])
for i in range(len(X_test_non)):
X_test[i,:,:,:]=X_test_non[i]
y_test=to_categorial(y_test_non,1001)
return X_test,y_test
test.py
import tensorflow as tf
import tensorflow.contrib.slim as slim
import tensorflow.contrib.slim.nets as nets
#from tensorflow.contrib.slim.nets.inception import inception_v3, inception_v3_arg_scope
from read_files import load_data
import numpy as np
height = 299
width = 299
channels = 3
test_dir='test02_299.npy'
# Create graph
X = tf.placeholder(tf.float32, shape=[None, height, width, channels])
with slim.arg_scope(nets.inception.inception_v3_arg_scope()):
logits, end_points = nets.inception.inception_v3(X, num_classes=1001,
is_training=False)
predictions = end_points["Predictions"]
saver = tf.train.Saver()
X_test,Y_test = load_data(test_dir) # your images, shape [batch_size, 299, 299, 3]
# Execute graph
with tf.Session() as sess:
saver.restore(sess, "./inception_v3.ckpt")
predictions_val = predictions.eval(feed_dict={X: X_test})
predicted_classes = np.argmax(predictions_val, axis=1)
print(predicted_classes)
我们可以看到其对应的预测结果,我们也可以将其和原来的标签进行匹配,看看inception_v3模型的准确率。
PS1:某个权值在ckpt文件中没有找到
在训练的时候,出现的最频繁的问题就是:什么权重没有在ckpt文件中找到,但是对应的权重都有,就很烦了,这时候问题可能有几个方面:
1)命名空间的问题,将权重文件放在某个命名空间中,而从这个权重文件中加载对应的权重,得到的权重和预期的带有命名空间的权重不匹配,所以找不到:
def model(x, logits=False, training=False):
#print ('the model is called',type(x),x.shape)
#with tf.variable_scope('model', reuse=True):
with slim.arg_scope(nets.inception.inception_v1_arg_scope()):
logits_, _ = nets.inception.inception_v1(x,num_classes=1001,is_training=training)
y = tf.nn.softmax(logits_)
if logits:
return y,logits_
return y
with tf.variable_scope('model1'):
env.x = tf.placeholder(tf.float32, (None, img_rows, img_cols, img_chas),
name='x')
env.y = tf.placeholder(tf.float32, (None, n_classes), name='y')
env.training = tf.placeholder(bool, (), name='mode')
#print '&&&&&&&&&&&'
#print env.x.shape
#print '&&&&&&&&&&&'
env.ybar, logits = model(env.x, logits=True, training=env.training)
with slim.arg_scope(nets.inception.inception_v1_arg_scope()):
init_fn = slim.assign_from_checkpoint_fn('D://./inception_v1.ckpt',slim.get_model_variables())
init_fn(sess)
这时候即便在下面的slim.arg_scope前面带上with tf.variable_scope(‘model1’,reuse=True):也没用,无法匹配!
2)给定的输入数据的格式不匹配,例如要求输入格式为(299,299,3),我们却给了(224,224,3),这时候报的错误仍旧是“在ckpt文件中没有找到什么权重”,真的很坑,找了很久才发现这个问题;
3)对应的权值文件里面可能真的没有这种权值,这时候我们就要去下载一份标准的ckpt文件,确保包含所有权值,底下给一个可以检测ckpt文件中权值名的代码:
4)你可能还会遇到
InvalidArgumentError (see above for traceback): Assign requires shapes of both tensors to match. lhs shape= [1000] rhs shape= [1001]
这种错误,不要伤心哈,问题在于:
logits_,_=nets.inception.inception_v3(X,reuse=None)在这儿并没有指定num_classes=???,需要显示指定出来就可以避免这个问题啦!
#coding=utf-8
import tensorflow as tf
import numpy as np
from tensorflow.python import pywrap_tensorflow
reader=pywrap_tensorflow.NewCheckpointReader("inception_v3.ckpt")
var_to_shape_map=reader.get_variable_to_shape_map()
print(var_to_shape_map)
for key in var_to_shape_map:
#这儿可以输入你对应的报错的权值名字
if key=="InceptionV3/AuxLogits/Conv2d_2a_3x3/BatchNorm/moving_variance":
print("找到!")
PS2:除了使用saver加载权重,我们也可以使用如下方式加载权重:
init_fn = slim.assign_from_checkpoint_fn(
os.path.join(checkpoints_dir, 'resnet_v1_101.ckpt'),
slim.get_model_variables('resnet_v1_101'))
with tf.Session() as sess:
init_fn(sess)
更多详细细节请看:
github_迁移学习