一. 理解keras的配置+图片转换为矩阵

在搭建自己的网络之前,我们首先看一下keras.json  这一个文件。

1. 理解keras.json 文件

keras.json 文件,打开它(如果找不到就在安装keras库里面搜索)

    打开之后是这样的:

{
    "epsilon": 1e-07,
    "floatx": "float32",
    "image_data_format": "channels_last",
    "backend": "tensorflow"
}

在里面,你可以看到四个重要的参数,我们一一说一下它的作用。

(1) epsilon: 防止作除法时,分母为0

(2)float32:定义精度

(3) backend:keras库使用tensorflow作为后端,你也可以使用theano作为后端,将其改为theano

(4) image_data_format: 这个非常重要,这个值有两个类型:channels_last 和channels_first

                                           在opencv中,我们知道也是(rows,columns,channels), 即channels_last类型。

                                           但是在theano的设定中是channel_first的设定。


2. 导入图片, 并将图片转换为矩阵处理(有很多程序,不过一劳永逸,保存为package)

将一个project保存为这样的形式,我们一步一步往里面加东西

|--- pyimagesearch
| |--- __init__.py
| |--- datasets
| | |--- __init__.py
| | |--- SimpleDatasetLoader.py   #根据类名大写
| |--- preprocessing
| | |--- __init__.py
| | |--- ImageToArrayPreprocessor.py  #根据类名大写
| | |--- SimplePreprocessor.py

关于init文件,都是空的,不过必须要建立起作用。

第一步,打开preprocessing文件夹里面的

ImageToArrayPreprocessor.py

添加程序如下,这一步主要是将图片转换成矩阵的形式:

from keras.preprocessing.image import img_to_array

class ImageToArrayPreprocessor:
    def __init__(self,dataFormat=None):
        self.dataFormat=dataFormat

    def preprocess(self,image):
        return img_to_array(image,data_format=self.dataFormat)

第二步,打开preprocessing文件夹里面的

SimplePreprocessor.py

添加程序如下,这一步主要是可以rezise图片到你自己想要的大小


# -*- coding: utf-8 -*-
 
 
import
 
 
class  
  SimplePreprocessor: 
 
 
 
def  
  __init__( 
  self, 
  width, 
  height, 
  inter=cv2.INTER_AREA): 
 
 
 
self.width=width 
 
 
 
self.height=height 
 
 
 
self.inter=inter 
 
 
 

            
 
 
 
def  
  preprocess( 
  self, 
  image): 
 
 
 
return cv2.resize(image,( 
  self.width, 
  self.height),  
  interpolation= 
  self.inter)



第三步,打开datasets里面的

SimpleDatasetLoader.py

添加程序如下,这一步骤主要作用为导入你需要的图片


# -*- coding: utf-8 -*-
 
 
import numpy  
  as
 
 
import
 
 
import
 
 
class  
  SimpleDatasetLoader: 
 
 
 
def  
  __init__( 
  self, 
  preprocessors= 
  None): 
 
 
 
self.preprocessors = preprocessors 
 
 
 

            
 
 
 
if  
  self.preprocessors is  
  None: 
 
 
 
self.preprocessors=[] 
 
 
 
def  
  load( 
  self, 
  imagePaths, 
  verbose=- 
  1): 
 
 
 

           data=[] 
 
 
 

           labels=[] 
 
 
 
for (i, imagePath) in  
  enumerate
 
 

               image =cv2.imread(imagePath)


2]  #这个非常重要,文件夹建立名称为类名,为label



if  
  self.preprocessors is not  
  None: 
 
 
 
for p in  
  self.preprocessors: 
 
 
 

                       image=p.preprocess(image) 
 
 
 

                        
 
 
 

               data.append(image) 
 
 
 

               labels.append(label) 
 
 
 
if verbose > 
  0 and i> 
  0 and (i+ 
  1)%verbose== 
  0: 
 
 
 
print( 
  '[INFO] processed {}/{}'.format(i+ 
  1, 
 
 
 
len(imagePaths))) 
 
 
 
return



完成了以上三个步骤,基本的图片输入和转换需要的程序就已经写好了,我们可以看一下主要的步骤

1. 导入图片

2. 改变图片大小

3. 选择通道维度

4. 输出矩阵


二. 建立一个简单的卷积网络 ShallowNet

第四步,先从简单的网络开始建立,我们建立我们的package如图所示,该conv文件集里面的shallownet为我们要做的网络:

--- pyimagesearch
| |--- __init__.py
| |--- datasets
| |--- nn
| | |--- __init__.py
...
| | |--- conv
| | | |--- __init__.py
| | | |--- ShallowNet.py
| |--- preprocessing

打开其文件,输入程序如下所示,为一个简单的卷积网络,后面我们会讲更加复杂的,不过现在来一点自己建立网络的满足感:


from keras.models  
  import
 
 
from keras.layers.convolutional  
  import
 
 
from keras.layers.core  
  import
 
 
from keras.layers.core  
  import
 
 
from keras.layers.core  
  import
 
 
from keras  
  import backend  
  as
 
 
class  
  ShallowNet: 
 
 
 
def  
  build( 
  width, 
  height, 
  depth, 
  classes): 
 
 
 

           model=Sequential() 
 
 
 

           inputShape=(height,width,depth) 
 
 
 
if K.image_data_format()== 
  'channel_first': 
 
 
 

               inputShape=(depth,height,width)    #我们之前讲的通道点 
 
 
 
32,( 
  3, 
  3), 
  padding= 
  'same', 
  input_shape=inputShape, 
  activation= 
  'relu')) 
 
 
 

           model.add(Flatten()) 
 
 
 
activation= 
  'softmax')) #根据自己的类别修改,类似于二分类为sigmoid 
 
 
 
return

最后一步,建立一个新的文件导入我们的图片以及开始训练

取名可以叫做shallownet_animals.py

程序如下:


from sklearn.preprocessing  
  import
 
 
from sklearn.model_selection  
  import
 
 
from sklearn.metrics  
  import
 
 
from pyimagesearch.preprocessing  
  import
 
 
from pyimagesearch.preprocessing  
  import
 
 
from pyimagesearch.datasets  
  import
 
 
from pyimagesearch.nn.conv  
  import
 
 
from keras.optimizers  
  import
 
 
from imutils  
  import
 
 
import matplotlib.pyplot  
  as
 
 
import numpy  
  as
 
 
import
 
 

   ap=argparse.ArgumentParser() 
 
 
 
'-d', 
  '--dataset', 
  required= 
  True, 
  help= 
  'path to the input dataset') 
 
 
 
vars(ap.parse_args()) 
 
 
 
print( 
  '[INFO] loading images...') 
 
 
 
list(paths.list_images(args[ 
  'dataset'])) 
 
 
 
32, 
  32) 
 
 
 

   iap=ImageToArrayPreprocessor.ImageToArrayPreprocessor() 
 
 
 
preprocessors=[sp,iap]) 
 
 
 
verbose= 
  500) 
 
 
 
'float')/ 
  255.0
 
 
test_size= 
  0.25, 
  random_state= 
  42) 
 
 
 

   train_y=LabelBinarizer().fit_transform(train_y) 
 
 
 

   test_y=LabelBinarizer().fit_transform(test_y) 
 
 
 
#print(train_x.shape)
 
 
#print(train_y)
 
 
print( 
  '[INFO] compiling models...') 
 
 
 
lr= 
  0.005) 
 
 
 
width= 
  32, 
  height= 
  32, 
  depth= 
  3, 
  classes= 
  1) 
 
 
 
loss= 
  'binary_crossentropy', 
  optimizer=opt, 
  metrics=[ 
  'accuracy']) #多分类的话为categorical_crossentropy 
 
 
 

print( 
  '[INFO] training network...') 
 
 
 
validation_data=(test_x,test_y), 
  batch_size= 
  32, 
  epochs= 
  100, 
  verbose= 
  1) 
 
 
 
print( 
  '[INFO] evaliatiing model...') 
 
 
 
batch_size= 
  32) 
 
 
 
print(classification_report(test_y.argmax( 
  axis= 
  1),predictions.argmax( 
  axis= 
  1), 
  target_names=[ 
  'cat', 
  'dog'])) 
 
 
 

"ggplot") 
 
 
 

   plt.figure() 
 
 
 
0,  
  100), H.history[ 
  "loss"],  
  label= 
  "train_loss") 
 
 
 
0,  
  100), H.history[ 
  "val_loss"],  
  label= 
  "val_loss") 
 
 
 
0,  
  100), H.history[ 
  "acc"],  
  label= 
  "train_acc") 
 
 
 
0,  
  100), H.history[ 
  "val_acc"],  
  label= 
  "val_acc") 
 
 
 
"Training Loss and Accuracy") 
 
 
 
"Epoch #") 
 
 
 
"Loss/Accuracy") 
 
 
 

   plt.legend() 
 
 
 

   plt.show()




这里我使用的数据库为网络上出名的dogs vs cats的数据库,我分别取了2000个狗和猫的图片进行分类。

注意这里非常重要的就是之前讲的分类图片文件夹的建立,

我这里的文件夹名称为 C:\animals   

在这个文件夹下面有C:\animals\cats和C:\animals\dogs,里面分别存图片。

在command windows里面输入以下的程序,就可以开始训练啦:

$ python shallownet_animals.py --dataset C:/animals

三. 总结

谢谢大家的学习,这个是我学习机器学习几个月来第一次写文来分享,如果有任何问题可以留言。

现在就可以开始训练自己的网络啦,后续我也会继续介绍其他的更加复杂的网络。

参考文献:

Howse J, Minichino J. Learning OpenCV 3 Computer Vision with Python[J]. 2015.