字节跳动面试:对于 Tersorflow 你怎么理解的,有做过人工智能的应用吗
file = h5py.File("dataset//data.h5","w")file.create_dataset('X', data=np.array(X))file.create_dataset('Y', data=np.array(Y))file.close()
#test
data = h5py.File("dataset//data.h5","r")
X_data = data['X']
print(X_data.shape)
Y_data = data['Y']
print(Y_data[123])
image = Image.fromarray(X_data[123]) #矩阵转图片并显示
image.show()
训练模型接下来就是训练模型了,首先把数据集划分为训练集和测试集,然后先坐下归一化,把标签转化为 one-hot 向量表示,代码如下:
#load datasetdef load_dataset():#划分训练集、测试集 data = h5py.File("dataset//data.h5","r")X_data = np.array(data['X']) #data['X']是 h5py._hl.dataset.Dataset 类型,转化为 arrayY_data = np.array(data['Y'])
print(type(X_data))
X_train, X_test, y_train, y_test = train_tes
t_split(X_data, Y_data, train_size=0.9, test_size=0.1, random_state=22)
print(X_train.shape)
print(y_train[456])
image = Image.fromarray(X_train[456])
image.show()
y_train = y_train.reshape(1,y_train.shape[0])
y_test = y_test.reshape(1,y_test.shape[0])
print(X_train.shape)
print(X_train[0])
X_train = X_train / 255. # 归一化 X_test = X_test / 255.
print(X_train[0])
one-hot
y_train = np_utils.to_categorical(y_train, num_classes=11)print(y_train.shape)y_test = np_utils.to_categorical(y_test, num_classes=11)print(y_test.shape)
return X_train, X_test, y_train, y_test
构建 CNN 模型,这里用了最简单的类 LeNet-5,具体两层卷积层、两层池化层、一层全连接层,一层 softmax 输出。具体的小 trick 有:dropout、relu、regularize、mini-batch、adam。具体看代码吧:
def weight_variable(shape):tf.set_random_seed(1)return tf.Variable(tf.truncated_normal(shape, stddev=0.1))
def bias_variable(shape):return tf.Variable(tf.constant(0.0, shape=shape))
def conv2d(x, W):return tf.nn.conv2d(x, W, strides=[1,1,1,1], padding='SAME')
def max_pool_2x2(z):return tf.nn.max_pool(z, ksize=[1,2,2,1], strides=[1,2,2,1], padding='SAME')
def random_mini_batches(X, Y, mini_batch_size=16, seed=0):"""Creates a list of random minibatches from (X, Y)
Arguments:X -- input data, of shape (input size, number of examples)Y -- true "label" vector (containing 0 if cat, 1 if non-cat), of shape (1, number of examples)mini_batch_size - size of the mini-batches, integerseed -- 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 examplesmini_batches = []np.random.seed(seed)
Step 1: Shuffle (X, Y)
permutation = list(np.random.permutation(m))shuffled_X = X[permutation]shuffled_Y = Y[permutation,:].reshape((m, Y.shape[1]))
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 partitionningfor 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 cnn_model(X_train, y_train, X_test, y_test, keep_prob, lamda, num_epochs = 450, minibatch_size = 16):X = tf.placeholder(tf.float32, [None, 64, 64, 3], name="input_x")y = tf.placeholder(tf.float32, [None, 11], name="input_y")kp = tf.placeholder_with_default(1.0, shape=(), name="keep_prob")lam = tf.placeholder(tf.float32, name="lamda")#conv1W_conv1 = weight_variable([5,5,3,32])b_conv1 = bias_variable([32])z1 = tf.nn.relu(conv2d(X, W_conv1) + b_conv1)maxpool1 = max_pool_2x2(z1) #max_pool1 完后 maxpool1 维度为[?,32,32,32]
#conv2W_conv2 = weight_variable([5,5,32,64])b_conv2 = bias_variable([64])z2 = tf.nn.relu(conv2d(maxpool1, W_conv2) + b_conv2)maxpool2 = max_pool_2x2(z2) #max_pool2,shape [?,16,16,64]
#conv3 效果比较好的一次模型是没有这一层,只有两次卷积层,隐藏单元 100,训练 20 次
W_conv3 = weight_variable([5, 5, 64, 128])
b_conv3 = bias_variable([128])
z3 = tf.nn.relu(conv2d(maxpool2, W_conv3) + b_conv3)
maxpool3 = max_pool_2x2(z3) # max_pool3,shape [?,8,8,128]
#full connection1W_fc1 = weight_variable([161664, 200])b_fc1 = bias_variable([200])maxpool2_flat = tf.reshape(maxpool2, [-1, 161664])z_fc1 = tf.nn.relu(tf.matmul(maxpool2_flat, W_fc1) + b_fc1)z_fc1_drop = tf.nn.dropout(z_fc1, keep_prob=kp)
#softmax layerW_fc2 = weight_variable([200, 11])b_fc2 = bias_variable([11])z_fc2 = tf.add(tf.matmul(z_fc1_drop, W_fc2),b_fc2, name="outlayer")prob = tf.nn.softmax(z_fc2, name="probability")#cost functionregularizer = tf.contrib.layers.l2_regularizer(lam)regularization = regularizer(W_fc1) + regularizer(W_fc2)cost = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits_v2(labels=y, logits=z_fc2)) + regularization
train = tf.train.AdamOptimizer().minimize(cost)
output_type='int32', name="predict"
pred = tf.argmax(prob, 1, output_type="int32", name="predict") # 输出结点名称 predict 方便后面保存为 pb 文件 correct_prediction = tf.equal(pred, tf.argmax(y, 1, output_type='int32'))accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))tf.set_random_seed(1) # to keep consistent results
seed = 0
init = tf.global_variables_initializer()with tf.Session() as sess:sess.run(init)for epoch in range(num_epochs):seed = seed + 1epoch_cost = 0.num_minibatches = int(X_train.shape[0] / minibatch_size)minibatches = random_mini_batches(X_train, y_train, minibatch_size, seed)for minibatch in minibatches:(minibatch_X, minibatch_Y) = minibatch_, minibatch_cost = sess.run([train, cost], feed_dict={X: minibatch_X, y: minibatch_Y, kp: keep_prob, lam: lamda})epoch_cost += minibatch_cost / num_minibatchesif epoch % 10 == 0:print("Cost after epoch %i: %f" % (epoch, epoch_cost))print(str((time.strftime('%Y-%m-%d %H:%M:%S'))))
这个 accuracy 是前面的 accuracy,tensor.eval()和 Session.run 区别很小
train_acc = accuracy.eval(feed_dict={X: X_train[:1000], y: y_train[:1000], kp: 0.8, lam: lamda})print("train accuracy", train_acc)test_acc = accuracy.eval(feed_dict={X: X_test[:1000], y: y_test[:1000], lam: lamda})print("test accuracy", test_acc)
#save modelsaver = tf.train.Saver({'W_conv1':W_conv1, 'b_conv1':b_conv1, 'W_conv2':W_conv2, 'b_conv2':b_conv2,'W_fc1':W_fc1, 'b_fc1':b_fc1, 'W_fc2':W_fc2, 'b_fc2':b_fc2})saver.save(sess, "model_500_200_c3//cnn_model.ckpt")#将训练好的模型保存为.pb 文件,方便在 Android studio 中使用 output_graph_def = graph_util.convert_variables_to_constants(sess, sess.graph_def, output_node_names=['predict'])with tf.gfile.FastGFile('model_500_200_c3//digital_gesture.pb', mode='wb') as f: # ’wb’中 w 代表写文件,b 代表将数据以二进制方式写入文件。f.write(output_graph_def.SerializeToString())
这里有一个非常非常非常重要的事情,要注意,具体请参考上一篇博客中的 2. 模型训练注意事项 链接为:将 TensorFlow 训练好的模型迁移到 Android APP 上(TensorFlowLite)。整个模型训练几个小时即可,当然调参更是门艺术活,不多说了。 ??这里小小感慨下,i7-7700k 跑一个 epoch 需要 2 分钟,750ti 需要 36 秒,1070 需要 6 秒。。。训练完的模型性能
评论