压缩技术不少,它们的用法和兼容性也各不相同。 html
压缩有两种主要类型:算法
例如,使用_Autoencoders_,咱们能够分解此图像并将其表示为下面的32矢量代码。使用它,咱们能够重建图像。固然,这是_有损_压缩的一个示例,由于咱们已经丢失了不少信息。数组
不过,咱们可使用彻底相同的技术,经过为表示分配更多的空间来更精确地作到这一点:网络
此任务有两个关键组件:app
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
使用inp
和reconstruction
参数建立一个连接它们,并使用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。
模型:
在本例中,咱们将比较构造的图像和原始图像,所以x
和y
都等于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)
如今,让咱们增长code_size
至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
。
咱们将为今生成的模型与以前的模型相同,尽管咱们将进行不一样的训练。此次,咱们将使用原始和相应的噪点图像对其进行训练:
如今让咱们看一下模型结果:
可用于主成分分析,这是一种降维技术,图像去噪等。