tensorflow生成图片标签_Tensorboard高维向量可视化 + 解决标签和图片不显示BUG
1.前言
本文就使用tensorboard進行高維向量可視化過程中出現的一些bug和問題,進行一次總結,幫助那些和我一樣的小白快速上手Tensorboard高維向量可視化。
這里我先展示下最近我做的高維向量可視化的成果,藍色是非事故圖片,紅色是事故圖片。從結果上看出來,模型對事故和非事故的區分能力還算可以。
事故和非事故二分類結果那么如何快速上手一個空間向量可視化過程,查看模型分類結果的空間分布呢?
這里我們使用到了tensorflow的tensorboard工具包,以事故分類為例,一步步克服tensorboard中的一些BUG。
2.特征向量提取與記錄
一般而言,類似圖像分類這種任務,在CNN最后幾層中,一般會添加1x1卷積或者是全連接層,將backbone(特征提取網絡)輸出的特征圖進行降維,便于接下來的分類。
在搭建模型的時候,也要刻意引出最后幾層全連接層(或1x1卷積層)的輸出,因為我們要可視化的高維向量就是這些層的輸出(具體層數的輸出維度,根據自己任務而定,這里我們在某一神經網絡的最后,加入了個維度為8的全連接層(用作可視化的高維向量),然后再接上一個維度為2的全連接層(為了分類))。
這里我們基于pytorch搭建了個模型,模型forward函數代碼如下:
def forward(self,x):batch_size, channels, height, width = x.size()feature_map=self.cnn(x)feature_map1=self.cnn_layer(feature_map)feature_map=feature_map1.view(batch_size,-1)output1=self.dense1(feature_map) #512 -> 64output2=self.dense2(output1) #64 -> 8output3=self.dense3(output2)#8 -> 2return output1,output2,output3可見,除了最后的輸入output3,我們還額外輸出了維度為64的output1和維度為8的output2。
等網絡訓練完畢后,我們就用訓練完的權重跑一遍測試集,將
- 每張測試集圖片的地址,
- 每張圖片經過網絡輸出的output1,
- 每張圖片經過網絡輸出的output2,
- 每張圖片經過網絡輸出的output3
保存到csv文件中,代碼如下
record=[]for original_image in tqdm(image_path):with torch.no_grad():# print('現在處理:', original_image)prep_img = image_process(original_image)prep_img=prep_img.cuda()# print(prep_img.shape)output1, output2, output3 = model(prep_img)# print(output1.shape)record.append([original_image,output1[0],output2[0],output3[0]])record_pd=pd.DataFrame(data=record,index=None,columns=['img_path','output64','output8',"output2"])record_pd.to_csv('vector_record.csv')保存的CSV的格式如下:
CSV格式可見,output可都是tensor類型的呀!
3. 標簽數據(meta.tsv)和圖片數據(sprite.jpg)生成
從上面可視化的結果來看,每個空間展示圖片的圖片內容和標簽(藍或紅)信息都被包含了,所以這里我們需要生成需要的標簽數據和圖片數據。我們從上面的csv文件中導入圖片的地址數據,因為知道了地址數據,我們就知道了圖片的內容以及標簽(因為非事故和事故數據集的地址不同,所以可以用地址的關鍵字判斷類別)
我們先定義一些變量,用作保存時的名稱:
# PROJECTOR需要的日志文件名和地址相關參數 LOG_DIR = 'log' SPRITE_FILE = 'sprite.jpg' META_FIEL = "meta.tsv" os.mkdir(LOG_DIR)接著加載數據:
# 數據加載 sample_data = pd.read_csv(r'E:Deep_learning_PytorchVideo_recognitionAccident_RecognitionCNN_LSTMAccident_Clustingsample_data.csv'3.1 載入圖片并生成一張大圖(sprite image)
這里我們先導入地址,然后將地址中的所有圖片導入進來并保存到一張list中(名為img_list)
img_path= sample_data['img_path'].values img_list=[] for path in img_path:img=cv2.imread(path,0)# print(img.shape)img=cv2.resize(img,(128,128))# print(img.shape)img_list.append(img.reshape(1,128,128))接著我們定義一個大圖像生成函數create_sprite_image,如下:
def create_sprite_image(images):"""Returns a sprite image consisting of images passed as argument. Images should be count x width x height"""if isinstance(images, list):images = np.array(images)img_h = images.shape[1] #112img_w = images.shape[2] #112# sprite圖像可以理解成是小圖片平成的大正方形矩陣,大正方形矩陣中的每一個元素就是原來的小圖片。于是這個正方形的邊長就是sqrt(n),其中n為小圖片的數量。n_plots = int(np.ceil(np.sqrt(images.shape[0]))) #根號下2000# 使用全1來初始化最終的大圖片。spriteimage = np.ones((img_h*n_plots, img_w*n_plots))for i in range(n_plots):for j in range(n_plots):# 計算當前圖片的編號this_filter = i*n_plots + jif this_filter < images.shape[0]:# 將當前小圖片的內容復制到最終的sprite圖像this_img = images[this_filter]spriteimage[i*img_h:(i + 1)*img_h,j*img_w:(j + 1)*img_w] = this_imgreturn spriteimage然后使用img_list生成這個大圖像并保存:
img=np.concatenate(img_list,0) #(2000, 112, 112) # 生成sprite圖像# to_visualise = 1 - np.reshape(img, (-1, 28, 28)) sprite_image = create_sprite_image(img)# 將生成的sprite圖片放到相應的日志目錄下 path_for_sprites = os.path.join(LOG_DIR, SPRITE_FILE) # plt.imsave(path_for_mnist_sprites,sprite_image, cmap='gray') cv2.imwrite(path_for_sprites,sprite_image,[int(cv2.IMWRITE_JPEG_QUALITY), 100])這里,sprite_image就生成好了,保存在log/sprite.jpg中。
3.2 生成標簽數據meta.tsv
我們的事故和非事故圖片集放在文件夾:
非事故:Z:Fast_datasetAccident_model_pretrainClassficationFalse_for_classificaition事故:
Z:Fast_datasetAccident_model_pretrainClassficationTrue_for_classification
這里我們可以看出,可以用圖片地址區分事故標簽(False為非事故,True為事故)
那么我們代碼這么寫:
# # 生成每張圖片對應的標簽文件并寫道相應的日志目錄下 path_for_metadata = os.path.join(LOG_DIR,META_FIEL) with open(path_for_metadata, 'w') as f:f.write("IndextLabeln")for index, path in enumerate(img_path):label=0 if 'False' in path else 1f.write("%dt%dn"%(index, label))即完成了對meta.csv的記錄,meta.csv里面是長這樣的。
到這里,標簽數據(meta.tsv)和圖片數據(sprite.jpg)就生成了,接下來到最后的數據的匹配和關聯+總日志文件生成。
4. 數據的匹配和關聯+總日志文件生成
上述,我們在CSV文件中保存了每個圖片在訓練好的模型的輸出向量,這個輸出向量可以看作圖片在淺層空間的表示。那我們就從該CSV文件導出需要的向量,這里我們以8維的向量為例子,導入的程序代碼如下:
sample_data = pd.read_csv(r'E:Deep_learning_PytorchVideo_recognitionAccident_RecognitionCNN_LSTMAccident_Clustingsample_data.csv')output= sample_data['output8'].valuesoutput=[eval(i).cpu().numpy() for i in output]# print(type(output2[0]))final_result=np.asarray(output)這段代碼需要注意的是,我們保存時候,向量以torch.tensor形式保存,從CSV導入的時候,輸出的類型又是字符串str類型,所以我們需要做兩件事
然后我們定義我們本文最重要的函數 visualisation(),代碼如下:
LOG_DIR = 'log' SPRITE_FILE = 'sprite.jpg' META_FIEL = 'meta.tsv' TENSOR_NAME = "zw" TRAINING_STEPS = 10def visualisation(final_result):# 使用一個新的變量來保存最終輸出層向量的結果,因為embedding是通過Tensorflow中變量完成的,所以PROJECTOR可視化的都是TensorFlow中的變哇。# 所以這里需要新定義一個變量來保存輸出層向量的取值y = tf.Variable(final_result, name=TENSOR_NAME)summary_writer = tf.summary.FileWriter(LOG_DIR)# 通過project.ProjectorConfig類來幫助生成日志文件config = projector.ProjectorConfig()# 增加一個需要可視化的bedding結果embedding = config.embeddings.add()# 指定這個embedding結果所對應的Tensorflow變量名稱embedding.tensor_name = y.name# Specify where you find the metadata# 指定embedding結果所對應的原始數據信息。比如這里指定的就是每一張MNIST測試圖片對應的真實類別。在單詞向量中可以是單詞ID對應的單詞。# 這個文件是可選的,如果沒有指定那么向量就沒有標簽。# embedding.metadata_path = META_FIELembedding.metadata_path = 'meta.tsv'# Specify where you find the sprite (we will create this later)# 指定sprite 圖像。這個也是可選的,如果沒有提供sprite 圖像,那么可視化的結果# 每一個點就是一個小困點,而不是具體的圖片。# embedding.sprite.image_path = SPRITE_FILEembedding.sprite.image_path = 'sprite.jpg'# 在提供sprite圖像時,通過single_image_dim可以指定單張圖片的大小。# 這將用于從sprite圖像中截取正確的原始圖片。embedding.sprite.single_image_dim.extend([128, 128])# Say that you want to visualise the embeddings# 將PROJECTOR所需要的內容寫入日志文件。projector.visualize_embeddings(summary_writer, config)# 生成會話,初始化新聲明的變量并將需要的日志信息寫入文件。sess = tf.InteractiveSession()sess.run(tf.global_variables_initializer())saver = tf.train.Saver()saver.save(sess, os.path.join(LOG_DIR, "model"), TRAINING_STEPS)sess.close()summary_writer.close()需要注意的是圖片的大小和上述第三部分定義的圖片大小應當一致!
然后接著上面,將final_result輸入到函數visualisation中,即可完成log日志的生成!
visualisation(final_result)log文件下的內容如下:
其中projector_config.pbtxt文件中的內容為
包含了各成員對應的關系
到最后,我們打開命令行CMD:
輸入
tensorboard --logdir=E:Deep_learning_PytorchVideo_recognitionAccident_RecognitionCNN_LSTMlog --host=127.0.0.1這里,一定注意--host!一定注意--host!一定注意--host!(重要的說三遍)
因為如果不輸入--host,選擇默認,那去網頁上就是打不開的!就算打開了,也沒有標簽文件和圖片數據的,這是花了我一個晚上血淋淋的教訓呀!
5.總結
關于如何快速上手Tensorboard的高維向量可視化,本篇文章算是比較詳細了!算是我一晚上的工作經驗吧!終于可以安心做其他事了!
總結
以上是生活随笔為你收集整理的tensorflow生成图片标签_Tensorboard高维向量可视化 + 解决标签和图片不显示BUG的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 传音 Infinix 手机 260W 快
- 下一篇: detectandcompute 图像尺