[PYTHON] _ 3rd day until good accuracy is obtained by Leaf Classification

I will finally implement it. This time, it is implemented by Chainer. ** chainer used 2.0.0 **. The version of chainer is

import chainer
chainer.__version__

You can check by doing.

Build

Pretreatment review

First of all, I will briefly review it. For image data etc., I downloaded Kaggle's Leaf Classification as it is and renamed the folder called images to images2.

resize

In the preprocessing of the code below, 1584 image data in the folder called images2 is changed to the image size of 32x32, and then saved in the folder called images.


images=[]
for i in range(1, 1585):
    image = cv2.imread("images2/%d.jpg "%i) #Extract from images2
    grayed = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    images.append(grayed) #Store in images

def resize_image(img):
    end_size = 32
    max_ = np.maximum(img.shape[0], img.shape[1])
    scale = end_size / max_
    height, width = img.shape
    size = (int(width*scale), int(height*scale))

    rescale_image = cv2.resize(img, size, interpolation=cv2.INTER_CUBIC)

    height, width = rescale_image.shape

    if width > height:
        z_pad = np.zeros([int((width-height)/2), width], dtype=np.uint8)
        end_image = np.vstack((z_pad, rescale_image, z_pad))
    else:
        z_pad = np.zeros([height, int((height - width)/2)], dtype=np.uint8)
        end_image = np.hstack((z_pad, rescale_image, z_pad))

    end_image = cv2.resize(end_image, (end_size, end_size))
    
    return end_image

for i,img in enumerate(images):
    cv2.imwrite("images/%d.jpg "%(i+1), resize_image(img)) #Store images in a folder called images

Creating a dataset

Now let's create a dataset that can be used for training from the training data.

dataset.py


import numpy as np
import pandas as pd
import cv2

#Train in Kaggle.Download csv and load it
#(train.Because csv only has labels)
train = pd.read_csv("train.csv")
labels=train["species"].values

#The labels now contain a string, so scikit it-Use the learn function to turn it into a number label
from sklearn import preprocessing
le = preprocessing.LabelEncoder()
le.fit(labels)
labels = le.transform(labels)
labels = labels.astype(np.int32)

#From the images folder, train.Bring the resized image from the id column of csv.
resized_images = []
for i in train.id:
    image = cv2.imread("images/%d.jpg "%i)
    grayed = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    resized_images.append(grayed)

#Convert to a type that can be read by chainer.
resized_images = np.array([resized_images])
resized_images = resized_images.reshape(-1, 1024).astype(np.float32)
resized_images /=255 #0~255 data to 0~Change to 1 data

#train_test_split is scikit-If the version of learn is new, cross_model instead of validation_It is in the selection.
#Create a data set for training from the matrix data and label data of the image.
from sklearn.cross_validation import train_test_split 
X_train, X_test, y_train, y_test = train_test_split(resized_images, labels, test_size=0.2, random_state=0)

#Specify the number to be used later.
N_train = y_train.size
N_test = y_test.size

By doing this, I was able to create a dataset.

Classify by NN

First, let's make it from NN instead of CNN.

NN_class.py


class MLP(chainer.Chain):
    
    def __init__(self):
        super().__init__(
            l1 = L.Linear(1024, 1000),
            l2 = L.Linear(1000, 900),
            l3 = L.Linear(900, 500),
            l4 = L.Linear(500, 99),
        )
        
    def __call__(self, x):
        h1 = F.relu(self.l1(x))
        h2 = F.relu(self.l2(h1))
        h3 = F.relu(self.l3(h2))
        return self.l4(h3)

here,

__call__

A description of the part can be found in How to use call method in Python class.

For the time being, input is 1024 (32x32), output is 99 (99 classification) So, it feels like connecting NN (neural network) and using the relu function as the activation function.

Model building

model.py


model = L.Classifier(MLP())

from chainer import optimizers
optimizer = optimizers.Adam()
optimizer.setup(model)

You have now created a model. On my PC ** I got an error when I set optimizer = chainer.optimizers.Adam () **, so in that case I think it's okay to write like this.

Run

NN_Run.py



batchsize = 99 #One batch size
n_epoch = 8 #Number of learning repetitions

train_loss = []
train_accuracy = []
test_loss = []
test_accuracy = []

for epoch in range(n_epoch):
    print("epoch", epoch+1)
    
    perm = np.random.permutation(N_train)
    
    sum_accuracy, sum_loss = 0,0
    
    for i in range(0, N_train, batchsize):
        X_batch = X_train[perm[i:i+batchsize]]
        y_batch = y_train[perm[i:i+batchsize]]
        
        
        optimizer.update(model, X_batch, y_batch)
        
        sum_loss += float(model.loss.data)
        sum_accuracy += float(model.accuracy.data)
        
        
    mean_loss = sum_loss/(N_train/batchsize)
    mean_accuracy = sum_accuracy/(N_train/batchsize)
    print("train_mean_loss={:.3f}, train_mean_accuracy={:.3f}".format(mean_loss, mean_accuracy))
    
    train_loss.append(model.loss.data)
    train_accuracy.append(model.accuracy.data)
    
    #There are few, so let's test it all
    sum_loss, sum_accuracy= 0,0
    
    for i in range(0, N_test, batchsize):
        X_batch = X_test[i:i+batchsize]
        y_batch = y_test[i:i+batchsize]
        
        loss = model(X_batch, y_batch)
        
        sum_loss += float(model.loss.data)
        sum_accuracy += float(model.accuracy.data)
        
    mean_loss = sum_loss/(N_test/batchsize)
    mean_accuracy = sum_accuracy/(N_test/batchsize)
    print("test_mean_loss={:.3f}, test_mean_accuracy={:.3f}".format(mean_loss, mean_accuracy))
    
    test_loss.append(model.loss.data)
    test_accuracy.append(model.accuracy.data)

The detailed explanation of the code part here is explained in a very easy-to-understand manner by the reference site, so I will omit it.

The rewritten part was N_train.size = 792, so I set batchsize = 99 and n_epoch = 8.

So the execution result is like this.

スクリーンショット 2017-07-19 1.59.28.png

Well, I'd like to understand that ** 99 classification was impossible with data for each 10 each. ** ** I will try to implement it on CNN as well.

CNN

Model building

model_CNN.py



class CNN(chainer.Chain):
    
    def __init__(self):
        super(CNN, self).__init__(
            conv1 = L.Convolution2D(1, 32, 5),
            conv2 = L.Convolution2D(32, 64, 5),
            conv3 = L.Convolution2D(64, 64, 5),
            l1 = L.Linear(None, 500),
            l2 = L.Linear(500, 99)
        )
        
    def __call__(self, x):
        x = x.reshape((len(x.data), 1, 32, 32))
        
        h = F.relu(self.conv1(x))
        h = F.max_pooling_2d(h, 2)
        h = F.relu(self.conv2(h))
        h = F.max_pooling_2d(h, 2)
        h = F.relu(self.conv3(h))
        h = F.max_pooling_2d(h, 2)
        h = F.dropout(F.relu(self.l1(h)))
        y = self.l2(h)
        return y

model = L.Classifier(CNN())

from chainer import optimizers
optimizer = optimizers.Adam()
optimizer.setup(model)

This is also easier to understand if you look at the site you referred to, so I will omit the explanation. And ** the execution code is exactly the same as the NN **, so I will only post the result.

スクリーンショット 2017-07-19 2.04.41.png

** ,,, that? ** ** I was impressed that the percentage of correct answers would be so low **. After all, it seems that ** we have to increase the number of datasets **. That's why it continues on the 4th day.

Referenced site

[Machine learning] I will explain while trying the deep learning framework Chainer. It's very easy to understand. Since FunctionSet etc. are not in 2.0.0, I think that you should do it while looking at other sites, but the explanation of relu function etc. is very polite. I borrowed the training code from here.

Try Chainer's MNIST sample This person is writing to give the model construction as the initial value of the argument, so I was able to somehow grasp what I was doing. I borrowed part of how to write a model for CNN from here.

Troubleshooting for chainer enjoyers This is the site I found when I searched for data error codes.

Recommended Posts

_ 3rd day until good accuracy is obtained by Leaf Classification
_ 2nd day until good accuracy is obtained by Leaf Classification
_1st day until good accuracy is obtained by Leaf Classification