def get_vector_from_label(label, batch_size):
data_flow_label = imageLoader.build(att, batch_size, label = label) #读取所有图片
origin = np.zeros(shape = vae.z_dim, dtype = 'float32') #原点向量
current_sum_pos = np.zeros(shape = vae.z_dim, dtype = 'float32') #将所有含有给定特征的图片向量加总
current_n_pos = 0 #统计当前具备给定特征的图片数量
current_mean_pos = np.zeros(shape = vae.z_dim, dtype = 'float32') #求加给定特征向量加总后的平均值向量
current_sum_neg = np.zeros(shape = vae.z_dim, dtype = 'float32') #不具备给定特征的向量加总
current_n_neg = 0 #不具备给定特征的向量个数
current_mean_neg = np.zeros(shape = vae.z_dim, dtype = 'float32') #不具备给定特征的向量加总后求平均所得向量
current_vector = np.zeros(shape = vae.z_dim, dtype = 'float32')
current_dist = 0 #给定图片特征向量与给定特征向量之间的距离
print('label: ' + label) #label表示给定特征
print('image : POS move : NEG move : distance : delta distance')
while current_n_pos < 10000:
batch = next(data_flow_label)
im = batch[0]
attribute = batch[1]
z = vae.encoder.predict(np.array(im)) #计算图片对应的特征向量
z_pos = z[attribute == 1] #抽取出具有给定特征图片所对应的向量
z_neg = z[attribute == -1] #抽取出不具备给定特征的图片所对应的向量
if len(z_pos) > 0:
current_sum_pos = current_sum_pos + np.sum(z_pos, axis = 0) #将所有含有给定特征的向量加总
current_n_pos += len(z_pos)
new_mean_pos = current_sum_pos / current_n_pos #计算平均向量
#随着图片加载越多,具有给定特征的图片也就越多,于是得到的平均向量在位置上就会发生改变
movement_pos = np.linalg.norm(new_mean_pos - current_mean_pos) #计算特征向量加总求平均后所得向量的变化量
if len(z_neg) > 0:
current_sum_neg = current_sum_neg + np.sum(z_neg, axis = 0) #将不具备给定特征的人脸向量加总
current_n_neg += len(z_neg)
new_mean_neg = current_sum_neg / current_n_neg #计算平均向量
#随着读入图片的增多,不具备给定特征的图片也会增多,于是平均向量也会发生改变
movement_neg = np.linalg.norm(new_mean_neg - current_mean_neg) #计算平均向量的改变量
current_vector = new_mean_pos - new_mean_neg #获得连接给定特征的平均向量和不具备给定特征的平均向量之间的连接向量
new_dist = np.linalg.norm(current_vector) #获得两个向量之间的距离
dist_change = new_dist - current_dist
print(str(current_n_pos) + ' : ' + str(np.round(movement_pos, 3))
+ ' : ' + str(np.round(movement_neg, 3))
+ ' : ' + str(np.round(new_dist, 3))
+ ' : ' + str(np.round(dist_change, 3))
)
current_mean_pos = np.copy(new_mean_pos)
current_mean_neg = np.copy(new_mean_neg)
current_dist = np.copy(new_dist)
if np.sum([movement_pos, movement_neg]) < 0.08: #当向量该变量足够小时我们结束对平均向量的计算
current_vector = current_vector / current_dist
print("Found the " + label + ' vector')
break
return current_vector
def add_vector_to_images(feature_vec): #将给定图片的向量滑向给定特征平均向量,于是让图片具备给定特征
n_to_show = 5
factors = [-4, -3, -2, -1, 0, 1, 2, 3, 4]
example_batch = next(data_flow_generic)
example_images = example_batch[0]
example_labels = example_batch[1]
z_points = vae.encoder.predict(example_images) #获得图片对应特征向量
fig = plt.figure(figsize = (18, 10))
counter = 1
for i in range(n_to_show):
img = example_images[i].squeeze()
sub = fig.add_subplot(n_to_show, len(factors) + 1, counter)
sub.axis('off')
sub.imshow(img) #显示没有变化前图片
counter += 1
for factor in factors: #让图片对应向量滑向给定特征平均向量
changed_z_point = z_points[i] + feature_vec * factor
changed_image = vae.decoder.predict(np.array([changed_z_point]))[0] #根据滑动后向量创建人脸图片
img = changed_image.squeeze()
sub = fig.add_subplot(n_to_show, len(factors) + 1, counter)
sub.axis('off')
sub.imshow(img)
counter += 1
plt.show()