如果你是以下一些机器学习的消息,你肯定看到了瑞恩·达尔所做的工作自动彩色化(黑客新闻评论,reddit的评论)。这个惊人的工作是采用像素hypercolumn从VGG-16网络,以便提取上色图像的信息。SAMIM还使用的网络来处理黑白视频帧和下面产生的惊人的视频:
https://www.youtube.com/watch?v=_MJU8VK2PI4
着色黑白电影与神经网络(由SAMIM视频,网络由Ryan)
但如何做到这一点hypercolumns作品?如何提取他们在这样的各种像素的分类问题使用?这篇文章的主要思想是使用具有Keras和Scikit-学习VGG-16预训练的网络一起,以提取像素hypercolumns并采取目前其上的信息的肤浅的样子。我写这篇文章,因为我还没有发现在Python什么做到这一点,这可能是别人对像素分类,分割等工作真的很有用
Hypercolumns
使用来自细胞神经网络(卷积神经网络)提供许多算法通常使用最后FC(完全连接)层,以便提供至约的某些输入摘录信息。然而,在过去的FC层中的信息可以是太粗糙空间,以允许精确定位(由于maxpooling等的序列),在另一侧中,第一层可以是在空间上精确,但将缺乏语义信息。为了得到两全其美的,的作者hypercolumn纸定义“上方”该像素的像素,因为所有的CNN单元的激活矢量的hypercolumn。

在hypercolumns的提取的第一步是将图像馈送到CNN(卷积神经网络)并提取特征图激活针对图像的每个位置。最棘手的部分是,当特征地图比输入图像更小,例如一个池操作之后,该论文的作者,然后做特征映射的双线性采样,以保持特征地图上输入相同的大小。也有与FC的问题(完全连接)层,因为可以不分离单元仅语义绑在图像的一个像素,所以FC激活被看作1×1的特征的地图,这意味着所有位置股关于hypercolumn的FC部分相同的信息。然后,所有这些激活被连接起来以创建hypercolumn。举例来说,如果我们把VGG-16架构的最大池操作后,仅使用前2卷积层,我们将与大小的hypercolumn:
64个过滤器(池之前第一CONV层)
+
128个过滤器(池之前第二CONV层)=192层的功能
这意味着图像的每个像素将具有192维向量hypercolumn。这hypercolumn真的很有趣,因为它包含关于第一层(在这里我们有很多的空间信息,但很少语义)关于最后几层,也信息(很少的空间信息和大量的语义的)信息。因此,本hypercolumn将大量的像素分类任务一定的帮助,如一个较早的自动着色的提及,因为每个位置hypercolumn携带什么这个像素语义上和空间上代表的信息。这也是上分割任务非常有帮助亚洲金博宝的(你可以看到更多有关原始文件介绍hypercolumn概念)。
一亚洲金博宝切听起来很酷,但我们如何在实践中提取hypercolumns?
VGG-16
Before being able to extract the hypercolumns, we’ll setup the VGG-16 pre-trained network, because you know, the price of a good GPU (I can’t even imagine many of them) here in Brazil is very expensive and I don’t want to sell my kidney to buy a GPU.

要设置上Keras预训练VGG-16网络,你需要下载文件的权重从这里(具有大约500MB vgg16_weights.h5文件),然后设置的体系结构和加载使用Keras下载的权重(关于权重文件和体系结构的详细信息这里):
从matplotlib进口pyplot如PLT进口theano进口CV2进口numpy的为NP进口SciPy的从keras.models SP导入顺序从keras.layers.core进口展平,密,差从keras.layers.convolutional进口Convolution2D,MaxPooling2D从keras.layers。Convolutional import ZeroPadding2D from keras.optimizers import SGD from sklearn.manifold import TSNE from sklearn import manifold from sklearn import cluster from sklearn.preprocessing import StandardScaler def VGG_16(weights_path=None): model = Sequential() model.add(ZeroPadding2D((1,1),input_shape=(3,224,224))) model.add(Convolution2D(64, 3, 3, activation='relu')) model.add(ZeroPadding2D((1,1))) model.add(Convolution2D(64, 3, 3, activation='relu')) model.add(MaxPooling2D((2,2), stride=(2,2))) model.add(ZeroPadding2D((1,1))) model.add(Convolution2D(128, 3, 3, activation='relu')) model.add(ZeroPadding2D((1,1))) model.add(Convolution2D(128, 3, 3, activation='relu')) model.add(MaxPooling2D((2,2), stride=(2,2))) model.add(ZeroPadding2D((1,1))) model.add(Convolution2D(256, 3, 3, activation='relu')) model.add(ZeroPadding2D((1,1))) model.add(Convolution2D(256, 3, 3, activation='relu')) model.add(ZeroPadding2D((1,1))) model.add(Convolution2D(256, 3, 3, activation='relu')) model.add(MaxPooling2D((2,2), stride=(2,2))) model.add(ZeroPadding2D((1,1))) model.add(Convolution2D(512, 3, 3, activation='relu')) model.add(ZeroPadding2D((1,1))) model.add(Convolution2D(512, 3, 3, activation='relu')) model.add(ZeroPadding2D((1,1))) model.add(Convolution2D(512, 3, 3, activation='relu')) model.add(MaxPooling2D((2,2), stride=(2,2))) model.add(ZeroPadding2D((1,1))) model.add(Convolution2D(512, 3, 3, activation='relu')) model.add(ZeroPadding2D((1,1))) model.add(Convolution2D(512, 3, 3, activation='relu')) model.add(ZeroPadding2D((1,1))) model.add(Convolution2D(512, 3, 3, activation='relu')) model.add(MaxPooling2D((2,2), stride=(2,2))) model.add(Flatten()) model.add(Dense(4096, activation='relu')) model.add(Dropout(0.5)) model.add(Dense(4096, activation='relu')) model.add(Dropout(0.5)) model.add(Dense(1000, activation='softmax')) if weights_path: model.load_weights(weights_path) return model
正如你所看到的,这是一个非常简单的代码(与Pytho亚洲金博宝n进口所需要的包一起)申报VGG16架构并加载预训练的权重。在此之后,我们将编译Keras模型:
模型= VGG_16( 'vgg16_weights.h5')SGD = SGD(LR = 0.1,衰减= 1E-6,动量= 0.9,涅斯捷罗夫=真)model.compile(优化= SGD,损耗= 'categorical_crossentropy')
现在,让我们来测试使用图像网络:
im_original = cv2.resize(cv2.imread( 'madruga.jpg'),(224,224))IM = im_original.transpose((2,0,1))IM = np.expand_dims(1M,轴= 0)im_converted= cv2.cvtColor(im_original,cv2.COLOR_BGR2RGB)plt.imshow(im_converted)
图片使用
正如我们所看到的,我们加载的图像,固定轴,然后我们就可以像现在送入VGG-16得到的预测:
OUT = model.predict(IM)plt.plot(out.ravel())

正如你所看到的,这些都是SOFTMAX层的最终激活,用类“运动衫,T恤,T恤”的范畴。
提取任意特征图
现在,提取特征地图的激活,我们必须能够提取特征从网络的任意卷积层映射。我们可以通过使用编译Theano功能做到这一点get_output()Keras的方法,如在下面的例子:
get_feature = theano.function([model.layers [0]。输入],model.layers [3] .get_output(列车= FALSE),allow_input_downcast =假)技艺= get_feature(IM)plt.imshow(技艺[0] [2])
特征映射
在上面的例子中,我编译Theano函数来获取3层(卷积层)的特征图,然后仅示出第三特征地图。在这里我们可以看到激活的强度。如果我们从功能,最终层激活的地图上,我们可以看到,提取的特征是比较抽象的,一样的眼睛,等看从15卷积层下面这个例子:
get_feature = theano.function([model.layers [0]。输入],model.layers [15] .get_output(列车= FALSE),allow_input_downcast =假)技艺= get_feature(IM)plt.imshow(技艺[0] [13])
更多的语义特征映射。
正如你所看到的,这第二个特征图提取更抽象的特点。而且你还可以注意到,当我们前面看到的功能相比,形象似乎更加捉襟见肘,这是因为第一个特征映射具有224×224大小,这其中有56×56,由于各层的缩小操作卷积层之前,这就是为什么我们失去了很多的空间信息。
提取hypercolumns
现在,终于让我们提取层的任意一组的hypercolumns。要做到这一点,我们将定义一个函数来提取这些hypercolumns:
DEF extract_hypercolumn(型号,layer_indexes,实例):层= [model.layers [LI] .get_output(列车=假),用于在layer_indexes LI] get_feature = theano.function([model.layers [0]。输入],层allow_input_downcast =假)feature_maps = get_feature(实例)hypercolumns = []用于feature_maps convmap:用于convmap FMAP [0]:=放大的sp.misc.imresize(FMAP,大小=(224,224),模式= “F”,口译= '双线性')hypercolumns.append(放大的)返回np.asarray(hypercolumns)
我们可以看到,这个功能会想到三个参数:模型本身,将被用于提取hypercolumn功能和将要用于提取hypercolumns图像实例层指标的清单。现在让我们来测试第2卷积层hypercolumn提取:
layers_extract = [3,8] HC = extract_hypercolumn(模型,layers_extract,IM)
就这样,我们提取的每个像素的hypercolumn载体。这个“HC”可变的形状是:(192L,224L,224L),这意味着我们为224×224像素中的每一个(总共50176个像素与每个192 hypercolumn功能)192维hypercolumn。
我们绘制的平均hypercolumns激活每个像素的:
平均= np.average(hc.transpose(1,2,0),轴= 2)plt.imshow(AVE)

广告可以看到,那些第一hypercolumn激活都在寻找像边缘检测,让我们来看看这些hypercolumns看起来像层22和29如何:
layers_extract = [22,29] HC = extract_hypercolumn(模型,layers_extract,1M)平均= np.average(hc.transpose(1,2,0),轴= 2)plt.imshow(AVE)

正如我们现在可以看到,功能真多抽象和语义有趣,但与空间信息有点模糊。
请记住,您可以提取使用所有的初始层,并最终层,包括FC层hypercolumns。在这里,我分别提取他们出示他们在可视化图的区别。
简单hypercolumn像素集群
Now, you can do a lot of things, you can use these hypercolumns to classify pixels for some task, to do automatic pixel colorization, segmentation, etc. What I’m going to do here just as an experiment, is to use the hypercolumns (from the VGG-16 layers 3, 8, 15, 22, 29) and then cluster it using KMeans with 2 clusters:
米= hc.transpose(1,2,0).reshape(50176,-1)k均值= cluster.KMeans(n_clusters = 2,max_iter = 300,n_jobs = 5,precompute_distances =真)cluster_labels = k均值.fit_predict(M)imcluster = np.zeros((224224))imcluster = imcluster.reshape((224 * 224))= imcluster cluster_labels plt.imshow(imcluster.reshape(224,224),CMAP = “热”)

现在,你可以想像是多么有用hypercolumns可以像关键点提取,分割等,这是一个非常优雅的,简单实用的理念任务。亚洲金博宝
我希望你喜欢它 !
- 基督教S. Perone