使用Python和Keras進行主成分分析、神經網絡構建圖像重建

原文連接:http://tecdat.cn/?p=8417

介紹

 

 

壓縮技術不少,它們的用法和兼容性也各不相同。 html

壓縮有兩種主要類型:算法

  • 無損:即便咱們不太「精打細算」,數據完整性和準確性也是首選
  • 有損:數據完整性和準確性並不像咱們提供服務的速度那麼重要-想象一下實時視頻傳輸,其中「實時」傳輸比擁有高質量視頻更爲重要

例如,使用_Autoencoders_,咱們能夠分解此圖像並將其表示爲下面的32矢量代碼。使用它,咱們能夠重建圖像。固然,這是_有損_壓縮的一個示例,由於咱們已經丟失了不少信息。數組

不過,咱們可使用徹底相同的技術,經過爲表示分配更多的空間來更精確地作到這一點:網絡

 

此任務有兩個關鍵組件:app

  •  
  •  對這二者進行共生訓練,以得到最有效的數據表示形式,咱們能夠從中重建原始數據,而不會丟失太多數據。

 

 經過使用均方偏差(MSE)將重建圖像與原始圖像進行比較來評估輸出-與原始圖像越類似,偏差就越小。

 

Keras是一個Python框架,可簡化神經網絡的構建。 框架

首先,讓咱們使用pip安裝Keras:dom

$pip install keras機器學習

預處理數據ide

一樣,咱們將使用LFW數據集。 函數

爲此,咱們將首先定義幾個路徑 :

ATTRS_NAME = "lfw_attributes.txt" IMAGES_NAME = "lfw-deepfunneled.tgz" RAW_IMAGES_NAME = "lfw.tgz"

而後,咱們將使用兩個函數-一個將原始矩陣轉換爲圖像並將顏色系統更改成RGB:

defdecode_image_from_raw_bytes(raw_bytes): img = cv2.imdecode(np.asarray(bytearray(raw_bytes), dtype=np.uint8),1) img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)returnimg

另外一個是實際加載數據集並使其適應咱們的需求:

defload_lfw_dataset( use_raw=False, dx=80, dy=80, dimx=45, dimy=45):_# Read attrs_df_attrs = pd.read_csv(ATTRS_NAME, sep='\t', skiprows=1) df_attrs = pd.DataFrame(df_attrs.iloc[:, :-1].values, columns=df_attrs.columns[1:]) imgs_with_attrs = set(map(tuple, df_attrs[["person","imagenum"]].values))_# Read photos_all_photos = [] photo_ids = []_# tqdm in used to show progress bar while reading the data in a notebook here, you can change__# tqdm_notebook to use it outside a notebook_withtarfile.open(RAW_IMAGES_NAMEifuse_rawelseIMAGES_NAME)asf:formintqdm.tqdm_notebook(f.getmembers()):_# Only process image files from the compressed data_ifm.isfile()andm.name.endswith(".jpg"):_# Prepare image_img = decode_image_from_raw_bytes(f.extractfile(m).read())_# Crop only faces and resize it_img = img[dy:-dy, dx:-dx] img = cv2.resize(img, (dimx, dimy))_# Parse person and append it to the collected data_fname = os.path.split(m.name)[-1] fname_splitted = fname[:-4].replace('_',' ').split() person_id =' '.join(fname_splitted[:-1]) photo_number = int(fname_splitted[-1])if(person_id, photo_number)inimgs_with_attrs: all_photos.append(img) photo_ids.append({'person': person_id,'imagenum': photo_number}) photo_ids = pd.DataFrame(photo_ids) all_photos = np.stack(all_photos).astype('uint8')_# Preserve photo_ids order!_all_attrs = photo_ids.merge(df_attrs, on=('person','imagenum')).drop(["person","imagenum"], axis=1)returnall_photos, all_attrs

 

咱們的數據X以3D矩陣的形式存在於矩陣中,這是RGB圖像的默認表示形式。經過提供三個矩陣-紅色,綠色和藍色,這三個矩陣的組合產生了圖像顏色。

這些圖像的每一個像素將具備較大的值,範圍從0到255。一般,在機器學習中,咱們傾向於使值較小,並以0爲中心,由於這有助於咱們的模型更快地訓練並得到更好的結果,所以讓咱們對圖像進行歸一化:

X = X.astype('float32') /255.0-0.5

如今,若是咱們測試X數組的最小值和最大值,它將是-.5.5,您能夠驗證:

print(X.max(), X.min())

0.5-0.5

爲了可以看到圖像,讓咱們建立一個show_image函數。0.5因爲像素值不能爲負,它將添加到圖像中:

如今,讓咱們快速瀏覽一下咱們的數據:

show_image(X[6])

面對

 如今讓咱們將數據分爲訓練和測試集:

sklearn train_test_split()函數可以經過給它測試比率來分割數據,其他的固然是訓練量。的random_state,你會看到不少機器學習,用來產生相同的結果,無論你有多少次運行代碼。

如今該模型了:

此函數將image_shape(圖像尺寸)和code_size(輸出表示的大小)做爲參數。 

從邏輯上講,該值越小code_size,圖像將壓縮得越多,可是保存的功能就越少,而且所複製的圖像與原始圖像的差別會更大。

因爲網絡體系結構不接受3D矩陣,所以該Flatten層的工做是將(32,32,3)矩陣展平爲一維數組(3072)。

 

 

如今,將它們鏈接在一塊兒並開始咱們的模型:

 以後,咱們經過Model使用inpreconstruction參數建立一個連接它們,並使用adamax優化器和mse損失函數對其進行編譯。

在這裏編譯模型意味着定義其目標以及達到目標的方式。在咱們的上下文中,目標是最小化,mse並經過使用優化程序來達到此目的-從本質上講,這是一種通過調整的算法,能夠找到全局最小值。

 結果:

_________________________________________________________________ Layer (type) Output Shape Param_#_================================================================= input_6 (InputLayer) (None,32,32,3)0_________________________________________________________________ sequential_3 (Sequential) (None,32)98336_________________________________________________________________ sequential_4 (Sequential) (None,32,32,3)101376================================================================= Total params:199,712Trainable params:199,712Non-trainable params:0_________________________________________________________________

在這裏咱們能夠看到輸入是32,32,3。 

 模型:

在本例中,咱們將比較構造的圖像和原始圖像,所以xy都等於X_train。理想狀況下,輸入等於輸出。

epochs變量定義多少次,咱們要訓練數據經過模型過去了,validation_data是咱們用來評估訓練後的模型驗證組:

Train on 11828 samples, validate on 1315 samples Epoch 1/20 11828/11828 [==============================] - 3s 272us/step - loss: 0.0128 - val_loss: 0.0087 Epoch 2/20 11828/11828 [==============================] - 3s 227us/step - loss: 0.0078 - val_loss: 0.0071 . . . Epoch 20/20 11828/11828 [==============================] - 3s 237us/step - loss: 0.0067 - val_loss: 0.0066

咱們能夠將 損失可視化,以得到 概述。

plt.plot(history.history['loss']) plt.plot(history.history['val_loss']) plt.title('model loss') plt.ylabel('loss') plt.xlabel('epoch') plt.legend(['train','test'], loc='upper left') plt.show()

損失/時代

咱們能夠看到,在第三個時期以後,損失沒有明顯的進展。 

這也可能致使模型過分擬合,從而使其在訓練和測試數據集以外的新數據上的表現不佳。

如今,最使人期待的部分-讓咱們可視化結果:

defvisualize(img,encoder,decoder):"""Draws original, encoded and decoded images"""_# img[None] will have shape of (1, 32, 32, 3) which is the same as the model input_code = encoder.predict(img[None])[0] reco = decoder.predict(code[None])[0] plt.subplot(1,3,1) plt.title("Original") show_image(img) plt.subplot(1,3,2) plt.title("Code") plt.imshow(code.reshape([code.shape[-1]//2,-1])) plt.subplot(1,3,3) plt.title("Reconstructed") show_image(reco) plt.show()foriinrange(5): img = X_test[i] visualize(img,encoder,decoder)

pca編碼器結果
pca編碼器結果2
pca編碼器結果3
pca編碼器結果4
pca編碼器結果5

 如今,讓咱們增長code_size1000

pca 1000結果
pca 1000結果
pca 1000結果
pca 1000結果
pca 1000結果

 

咱們剛剛作的就是_主成分分析_(PCA),這是一種_降維_技術。咱們能夠經過生成較小的新功能來使用它來減少功能集的大小,可是仍然能夠捕獲重要信息。

主成分分析是 一種很是流行的用法。

圖像去噪

 另外一種流行用法是去噪。讓咱們在圖片中添加一些隨機噪聲:

defapply_gaussian_noise(X, sigma=0.1): noise = np.random.normal(loc=0.0, scale=sigma, size=X.shape)returnX + noise

在這裏,咱們從標準正態分佈中添加了一些隨機噪聲,其大小爲sigma,默認爲0.1

做爲參考,這是具備不一樣sigma值的噪聲的樣子:

plt.subplot(1,4,1) show_image(X_train[0]) plt.subplot(1,4,2) show_image(apply_gaussian_noise(X_train[:1],sigma=0.01)[0]) plt.subplot(1,4,3) show_image(apply_gaussian_noise(X_train[:1],sigma=0.1)[0]) plt.subplot(1,4,4) show_image(apply_gaussian_noise(X_train[:1],sigma=0.5)[0])

噪聲

正如咱們所看到的,幾乎看不到圖像的sigma增長0.5。咱們將嘗試從σ爲的嘈雜圖像中再生原始圖像0.1

咱們將爲今生成的模型與以前的模型相同,儘管咱們將進行不一樣的訓練。此次,咱們將使用原始和相應的噪點圖像對其進行訓練:

如今讓咱們看一下模型結果:

去噪

去噪

 

結論

 可用於主成分分析,這是一種降維技術,圖像去噪等。

相關文章
相關標籤/搜索