日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

tensorflow生成图片标签_Tensorboard高维向量可视化 + 解决标签和图片不显示BUG

發(fā)布時間:2023/12/19 编程问答 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 tensorflow生成图片标签_Tensorboard高维向量可视化 + 解决标签和图片不显示BUG 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

1.前言

本文就使用tensorboard進行高維向量可視化過程中出現(xiàn)的一些bug和問題,進行一次總結(jié),幫助那些和我一樣的小白快速上手Tensorboard高維向量可視化。

這里我先展示下最近我做的高維向量可視化的成果,藍色是非事故圖片,紅色是事故圖片。從結(jié)果上看出來,模型對事故和非事故的區(qū)分能力還算可以。

事故和非事故二分類結(jié)果

那么如何快速上手一個空間向量可視化過程,查看模型分類結(jié)果的空間分布呢?

這里我們使用到了tensorflow的tensorboard工具包,以事故分類為例,一步步克服tensorboard中的一些BUG。

2.特征向量提取與記錄

一般而言,類似圖像分類這種任務(wù),在CNN最后幾層中,一般會添加1x1卷積或者是全連接層,將backbone(特征提取網(wǎng)絡(luò))輸出的特征圖進行降維,便于接下來的分類。

在搭建模型的時候,也要刻意引出最后幾層全連接層(或1x1卷積層)的輸出,因為我們要可視化的高維向量就是這些層的輸出(具體層數(shù)的輸出維度,根據(jù)自己任務(wù)而定,這里我們在某一神經(jīng)網(wǎng)絡(luò)的最后,加入了個維度為8的全連接層(用作可視化的高維向量),然后再接上一個維度為2的全連接層(為了分類))。

這里我們基于pytorch搭建了個模型,模型forward函數(shù)代碼如下:

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。

等網(wǎng)絡(luò)訓(xùn)練完畢后,我們就用訓(xùn)練完的權(quán)重跑一遍測試集,將

  • 每張測試集圖片的地址,
  • 每張圖片經(jīng)過網(wǎng)絡(luò)輸出的output1,
  • 每張圖片經(jīng)過網(wǎng)絡(luò)輸出的output2,
  • 每張圖片經(jīng)過網(wǎng)絡(luò)輸出的output3

保存到csv文件中,代碼如下

record=[]for original_image in tqdm(image_path):with torch.no_grad():# print('現(xiàn)在處理:', 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. 標(biāo)簽數(shù)據(jù)(meta.tsv)和圖片數(shù)據(jù)(sprite.jpg)生成

從上面可視化的結(jié)果來看,每個空間展示圖片的圖片內(nèi)容和標(biāo)簽(藍或紅)信息都被包含了,所以這里我們需要生成需要的標(biāo)簽數(shù)據(jù)和圖片數(shù)據(jù)。我們從上面的csv文件中導(dǎo)入圖片的地址數(shù)據(jù),因為知道了地址數(shù)據(jù),我們就知道了圖片的內(nèi)容以及標(biāo)簽(因為非事故和事故數(shù)據(jù)集的地址不同,所以可以用地址的關(guān)鍵字判斷類別)

我們先定義一些變量,用作保存時的名稱:

# PROJECTOR需要的日志文件名和地址相關(guān)參數(shù) LOG_DIR = 'log' SPRITE_FILE = 'sprite.jpg' META_FIEL = "meta.tsv" os.mkdir(LOG_DIR)

接著加載數(shù)據(jù):

# 數(shù)據(jù)加載 sample_data = pd.read_csv(r'E:Deep_learning_PytorchVideo_recognitionAccident_RecognitionCNN_LSTMAccident_Clustingsample_data.csv'

3.1 載入圖片并生成一張大圖(sprite image)

這里我們先導(dǎo)入地址,然后將地址中的所有圖片導(dǎo)入進來并保存到一張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))

接著我們定義一個大圖像生成函數(shù)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為小圖片的數(shù)量。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):# 計算當(dāng)前圖片的編號this_filter = i*n_plots + jif this_filter < images.shape[0]:# 將當(dāng)前小圖片的內(nèi)容復(fù)制到最終的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圖片放到相應(yīng)的日志目錄下 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 生成標(biāo)簽數(shù)據(jù)meta.tsv

我們的事故和非事故圖片集放在文件夾:

非事故:Z:Fast_datasetAccident_model_pretrainClassficationFalse_for_classificaition
事故:
Z:Fast_datasetAccident_model_pretrainClassficationTrue_for_classification

這里我們可以看出,可以用圖片地址區(qū)分事故標(biāo)簽(False為非事故,True為事故)

那么我們代碼這么寫:

# # 生成每張圖片對應(yīng)的標(biāo)簽文件并寫道相應(yīng)的日志目錄下 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里面是長這樣的。

到這里,標(biāo)簽數(shù)據(jù)(meta.tsv)和圖片數(shù)據(jù)(sprite.jpg)就生成了,接下來到最后的數(shù)據(jù)的匹配和關(guān)聯(lián)+總?cè)罩疚募伞?/p>

4. 數(shù)據(jù)的匹配和關(guān)聯(lián)+總?cè)罩疚募?/h2>

上述,我們在CSV文件中保存了每個圖片在訓(xùn)練好的模型的輸出向量,這個輸出向量可以看作圖片在淺層空間的表示。那我們就從該CSV文件導(dǎo)出需要的向量,這里我們以8維的向量為例子,導(dǎo)入的程序代碼如下:

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導(dǎo)入的時候,輸出的類型又是字符串str類型,所以我們需要做兩件事

  • 字符串轉(zhuǎn)torch.tensor,這里使用eval()函數(shù),且需要from torch import tensor
  • torch.tensor轉(zhuǎn)數(shù)組,因為后面要用tensorflow的tensorboard,所以需要轉(zhuǎn)成numpy。
  • 然后我們定義我們本文最重要的函數(shù) visualisation(),代碼如下:

    LOG_DIR = 'log' SPRITE_FILE = 'sprite.jpg' META_FIEL = 'meta.tsv' TENSOR_NAME = "zw" TRAINING_STEPS = 10def visualisation(final_result):# 使用一個新的變量來保存最終輸出層向量的結(jié)果,因為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結(jié)果embedding = config.embeddings.add()# 指定這個embedding結(jié)果所對應(yīng)的Tensorflow變量名稱embedding.tensor_name = y.name# Specify where you find the metadata# 指定embedding結(jié)果所對應(yīng)的原始數(shù)據(jù)信息。比如這里指定的就是每一張MNIST測試圖片對應(yīng)的真實類別。在單詞向量中可以是單詞ID對應(yīng)的單詞。# 這個文件是可選的,如果沒有指定那么向量就沒有標(biāo)簽。# embedding.metadata_path = META_FIELembedding.metadata_path = 'meta.tsv'# Specify where you find the sprite (we will create this later)# 指定sprite 圖像。這個也是可選的,如果沒有提供sprite 圖像,那么可視化的結(jié)果# 每一個點就是一個小困點,而不是具體的圖片。# 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所需要的內(nèi)容寫入日志文件。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()

    需要注意的是圖片的大小和上述第三部分定義的圖片大小應(yīng)當(dāng)一致!

    然后接著上面,將final_result輸入到函數(shù)visualisation中,即可完成log日志的生成!

    visualisation(final_result)

    log文件下的內(nèi)容如下:

    其中projector_config.pbtxt文件中的內(nèi)容為

    包含了各成員對應(yīng)的關(guān)系

    到最后,我們打開命令行CMD:

    輸入

    tensorboard --logdir=E:Deep_learning_PytorchVideo_recognitionAccident_RecognitionCNN_LSTMlog --host=127.0.0.1

    這里,一定注意--host!一定注意--host!一定注意--host!(重要的說三遍)

    因為如果不輸入--host,選擇默認,那去網(wǎng)頁上就是打不開的!就算打開了,也沒有標(biāo)簽文件和圖片數(shù)據(jù)的,這是花了我一個晚上血淋淋的教訓(xùn)呀!

    5.總結(jié)

    關(guān)于如何快速上手Tensorboard的高維向量可視化,本篇文章算是比較詳細了!算是我一晚上的工作經(jīng)驗吧!終于可以安心做其他事了!

    總結(jié)

    以上是生活随笔為你收集整理的tensorflow生成图片标签_Tensorboard高维向量可视化 + 解决标签和图片不显示BUG的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。