[Autopilot] Build a Traffic Sign Recognition Program

Hits: 0

See [“How to do deep learning traffic sign recognition with 98% accuracy? “] At the time of this article, I discovered udacity’s [autonomous driving] course. It’s a pity that there is a fee, but the course project is available on github, so just do the project directly, and there is no class.

Let’s start with the Build a Traffic Sign Recognition Program.

Environmental preparation

[The official docker environment] for the CPU is provided , which is a little uncomfortable. My brother’s 1060 has been eating dust for a long time, and I want to use it. However, it can be found that the Dockerfile.gpu file is also provided in the project. In fact, it is good to build it yourself, but because of the evil firewall, there will be problems with the network connection, and the speed is very slow, which is worrying. It was only later that I figured out how to connect.
It is useless to export https_proxy directly, it will enter the docker environment during docker build. At this point, the agent will fail.

The host can use ifconfig to see that there is a docker0 network card. In the docker environment, this ip is actually used to access the host. For example, the host is 172.17.0.1, and the docker is 172.17.0.2. Then ss is set to monitor on 172.17.0.1, and it is matched in gui-config.json. "shareOverLan": trueThere is a problem with the socks5 mode connection, so it must be changed to http. Then change the Dockerfile and add the correct export https_proxy.

However, I violently created the environment on the host machine conda env, then copied it into docker, and finally corrected the path of the conda-meta directory with sed. I installed a TensorFlow docker before, based on this environment, I completed the conda env, and then docker commit <CONTAINER ID> <IMAGE>saved this modified version of the environment.

Then use this to start the experiment. Open jupyter directly on the
nvidia-docker run -it -p 8888:8888 --volume /home/dinosoft/CarND-Traffic-Sign-Classifier-Project:/notebooks carnd bash
command line without adding bash. At this time, you want to ctrl+z to pause, and then pip can’t install something.

If the environment has changed, ctrl+p ctrl+q can exit the docker environment, then docker ps to view the id, and docker commit to save it.

conda env

After entering bash, remember to cut the environment. Otherwise, pip installs new packages and installs them elsewhere.

source activate carnd-term1

  # To deactivate an active environment, use:
  source deactivate

jupyter

#Install this first, support conda's env 
conda install nb_conda

Because this notebook is too long, it hurts to scroll the mouse, I need something like a directory for easy navigation

First install https://github.com/ipython-contrib/jupyter_contrib_nbextensions , and then check the table of content plugin to make it take effect.

data download

There should be a download link for the course materials, but unfortunately I didn’t pay. Fortunately, I finally found it. Otherwise, you have to download the data on the official website yourself, and then convert it hard.
[https://github.com/frankkanis/CarND-Traffic-Sign-Classifier-ProjectHere] provides the data download link in pickle format. There are so many kind people.

There are many people asking for data, I will move it to Baidu Cloud. Link: https://pan.baidu.com/s/1XSvdVrFFkr0oKvM0JWt46A Password: nb44

In this environment, I vomited a big mouthful of old blood, and it hurts.

Analysis of existing results and experiments

[https://github.com/kenshiro-o/CarND-Traffic-Sign-Classifier-Project] There is already a ready-made code here. Now I don’t have a lot of time to go to work, so let’s base it on this.

method baseline score normalised best score dropout
color 0.9145(5*5) 0.9310(3*3) 0.9754(0.5 3*3)
gray 0.9165(3*3) 0.9363(5*5) 0.9755(0.5 3*3)
hist_eq (iteration 500 times) 0.9339(3*3) 0.9775(5*5)
aug (2000 iterations) 0.9786(0.5 3*3)

The hand-craft operation of histogram equalization and data augmentation is actually limited (good news for lazy people like me), and the author is very tricky and secretly increases the number of iterations. In fact, normalization does not improve the effect of the model, but it is convenient to accelerate the convergence (note that the comparison here is under the same number of iterations (200)). Because of this data, DL can easily overfit, only the dropout improvement is the most obvious.

Thinking of other issues (only for the current scene, do not promote blindly):

Q: The effect of color on recognition

Although humans are still more sensitive to color, it can be seen from the results that under the same number of iterations, the grayscale image effect is slightly better.
If you look closely, you can find that there is a strong distinction between patterns and colors in the design of traffic signs (there are no signs with similar shapes, but different colors), so the color information in the current scene is a bit redundant. Still useful for distinguishing between logos and backgrounds.

Q: The problem of uneven distribution of categories

The distributions of valid and test sets are the same, and there is no weighting of different categories when calculating the accuracy rate. In fact, there is no problem at all.

Q: Normalization

def normalise_images(imgs, dist):
    """
    Nornalise the supplied images from data in dist
    """
    std = np.std(dist)
    #std = 128
    mean = np.mean(dist)
    #mean = 128
    return (imgs - mean) / std

The original author used this, and did not distinguish between color channels. Although it is common to do it in 3 channels.

Because I found that the brightness of the data pictures is different, I tried to correct each picture and each channel separately, and found that it took a lot of effort, and there was no special effect (multiplied by 255 to facilitate the direct display as a picture), the human eye thinks It’s hard to get up, and DL may not be able to see clearly.

def normalise_images_new(imgs, _):
      """
      Nornalise the supplied images from data in dist
      """
      result = []
      for i in range(imgs.shape[0]):
          img = imgs[i]
          range_max = np.max(img, axis=(0,1))
          range_min = np.min(img, axis=(0,1))
          mean = np.mean(img, axis=(0,1))
          std = np.std(img, axis=(0,1))
          if len(range_max.shape) == 1 and range_max.shape[0] > 1:
              tmp = np.zeros(img.shape)
              for j in range(range_max.shape[0]):
                  tmp[:, :, j] = (img[:, :, j] - range_min[j]) / (0.0 + range_max[j]-range_min[j]) * 255
              result.append(tmp)
          else:
              result.append((img - range_min) / (range_max-range_min) * 255)

      return np.array( np.clip(result, 0, 255) ).astype(np.uint8)

The original author finally used Histogram Equalization, which is essentially a linear transformation of the image, but this linear transformation matrix is ​​calculated separately for each image. So no big miracle should happen.

Vigorously miracle

In fact, this kind of problem still uses fine tuning based on the existing network. Try it out with vgg16.
main reference

vgg requires the input of 224224, and you have to scale 3232. The result is that the memory is burst. I directly intercept 1w and 1k for train and valid. At the beginning, I took the first 1w samples, which are uneven, and some labels were not obtained. . The result of running out makes people doubt life. Fortunately, find out the reason before going to bed, otherwise the model will run away overnight.

Using the complete vgg16 will explode the video memory, only reduce the fc layer added later, and then reduce the batch size.

from keras.models import Sequential
from keras.optimizers import SGD
from keras.layers import Input, Dense, Convolution2D, MaxPooling2D, AveragePooling2D, ZeroPadding2D, Dropout, Flatten, merge, Reshape, Activation
import cv2
import pickle
from sklearn.metrics import log_loss
import numpy as np


img_rows, img_cols = 224, 224 # Resolution of inputs
channel = 3
num_classes = 43


datasets_path = "./datasets/german_traffic_signs/"
models_path = "./models/"

training_file = datasets_path + 'train.p'
validation_file= datasets_path + 'valid.p'
testing_file = datasets_path + 'test.p'

with open(training_file, mode='rb') as f:
    train = pickle.load(f)
with open(validation_file, mode='rb') as f:
    valid = pickle.load(f)
with open(testing_file, mode='rb') as f:
    test = pickle.load(f)

X_train, y_train = train['features'], train['labels']
X_valid, y_valid = valid['features'], valid['labels']
X_test, y_test = test['features'], test['labels']

def normalise_image(X):
    result = []
    for img in X:
        im = cv2.resize(img, (224, 224)).astype(np.float32)
        im[:,:,0] -= 103.939
        im[:,:,1] -= 116.779
        im[:,:,2] -= 123.68
        #im = im.transpose((2,0,1))
        result.append(im/255.0)
    return np.array(result)

r_index = np.random.choice(len(X_train), 10000) 
X_train=normalise_image(X_train[r_index])
y_train=y_train[r_index]

r_index=np.random.choice(len(X_valid), 1000)
X_valid=normalise_image(X_valid[r_index])
y_valid=y_valid[r_index]

#one hot y
new_y = np.zeros((len(y_valid), num_classes))
new_y[np.range( len (y_valid)), y_valid] = 1
y_valid = new_y.astype(np.int8)

new_y = np.zeros((len(y_train), num_classes))
new_y[np.arange(len(y_train)), y_train] =1
y_train = new_y.astype(np.int8)


# test use the full amount, the memory seems to explode, after training, save the model and then run
X_test=normalise_image(X_test)

new_y = np.zeros((len(y_test), num_classes))
new_y[np.arange( len (y_test)), y_test] = 1
y_test = new_y.astype(np.int8)


# Check if each category number has 
np.sum(y_valid, axis= 0 )
np.sum(y_train,axis=0)


from keras import backend as K 
K.set_image_dim_ordering('tf') 
from keras import applications
base_model = applications.VGG16(weights='imagenet', include_top=False, input_shape=(img_rows, img_cols, channel))

from keras.models import Model
x = base_model.output

# Blindly add these layers
x = Flatten()(x)
x = Dense(32, activation='relu')(x)
x=  Dropout(0.5)(x)
predictions = Dense(num_classes, activation='softmax')(x)

# this is the model we will train
model = Model(input=base_model.input, output=predictions)

sgd = SGD(lr=1e-3, decay=1e-6, momentum=0.9, nesterov=True)
model.compile(optimizer=sgd, loss='categorical_crossentropy', metrics=['accuracy'])

batch_size = 40
nb_epoch = 100
# Start Fine-tuning
model.fit(X_train, y_train,
          batch_size=batch_size,
          nb_epoch=nb_epoch,
          shuffle=True,
          verbose=1,
          validation_data=(X_valid, y_valid),
          )

One epoch in 5 minutes, and it still uses GPU, I can’t imagine using CPU.

Train on 10000 samples, validate on 1000 samples
Epoch 1/100
10000/10000 [==============================] – 301s – loss: 3.4573 – acc: 0.0940 – val_loss: 2.3256 – val_acc: 0.3370
Epoch 2/100
10000/10000 [==============================] – 292s – loss: 2.2340 – acc: 0.3346 – val_loss: 1.0591 – val_acc: 0.7060
Epoch 3/100
10000/10000 [==============================] – 288s – loss: 1.3982 – acc: 0.5568 – val_loss: 0.6324 – val_acc: 0.8330
Epoch 4/100
10000/10000 [==============================] – 286s – loss: 0.8322 – acc: 0.7297 – val_loss: 0.1478 – val_acc: 0.9670
Epoch 5/100
10000/10000 [==============================] – 286s – loss: 0.5617 – acc: 0.8179 – val_loss: 0.0939 – val_acc: 0.9710
Epoch 6/100
10000/10000 [==============================] – 285s – loss: 0.4264 – acc: 0.8639 – val_loss: 0.0838 – val_acc: 0.9840
Epoch 7/100
10000/10000 [==============================] – 284s – loss: 0.3375 – acc: 0.8887 – val_loss: 0.0623 – val_acc: 0.9890
Epoch 8/100
10000/10000 [==============================] – 284s – loss: 0.2885 – acc: 0.9068 – val_loss: 0.0460 – val_acc: 0.9910
Epoch 9/100
10000/10000 [==============================] – 283s – loss: 0.2532 – acc: 0.9188 – val_loss: 0.0634 – val_acc: 0.9850
Epoch 10/100
10000/10000 [==============================] – 283s – loss: 0.2624 – acc: 0.9129 – val_loss: 0.0675 – val_acc: 0.9860
Epoch 11/100
10000/10000 [==============================] – 283s – loss: 0.2250 – acc: 0.9275 – val_loss: 0.0374 – val_acc: 0.9900
Epoch 12/100
10000/10000 [==============================] – 284s – loss: 0.1994 – acc: 0.9307 – val_loss: 0.0526 – val_acc: 0.9850
Epoch 13/100
10000/10000 [==============================] – 283s – loss: 0.1900 – acc: 0.9361 – val_loss: 0.0542 – val_acc: 0.9910
Epoch 14/100
10000/10000 [==============================] – 283s – loss: 0.1891 – acc: 0.9360 – val_loss: 0.0565 – val_acc: 0.9860
Epoch 15/100
10000/10000 [==============================] – 284s – loss: 0.1747 – acc: 0.9374 – val_loss: 0.0284 – val_acc: 0.9920
Epoch 16/100
10000/10000 [==============================] – 283s – loss: 0.1716 – acc: 0.9394 – val_loss: 0.0675 – val_acc: 0.9900
Epoch 17/100
10000/10000 [==============================] – 283s – loss: 0.1567 – acc: 0.9456 – val_loss: 0.0299 – val_acc: 0.9930
Epoch 18/100
10000/10000 [==============================] – 283s – loss: 0.1734 – acc: 0.9415 – val_loss: 0.0593 – val_acc: 0.9880
Epoch 19/100
10000/10000 [==============================] – 283s – loss: 0.1601 – acc: 0.9425 – val_loss: 0.0451 – val_acc: 0.9930
Epoch 20/100
10000/10000 [==============================] – 283s – loss: 0.1567 – acc: 0.9463 – val_loss: 0.0492 – val_acc: 0.9920
Epoch 21/100
10000/10000 [==============================] – 283s – loss: 0.1537 – acc: 0.9456 – val_loss: 0.0306 – val_acc: 0.9910
Epoch 22/100
10000/10000 [==============================] – 284s – loss: 0.1501 – acc: 0.9488 – val_loss: 0.0297 – val_acc: 0.9910
Epoch 23/100
10000/10000 [==============================] – 283s – loss: 0.1469 – acc: 0.9509 – val_loss: 0.0341 – val_acc: 0.9920
Epoch 24/100
10000/10000 [==============================] – 283s – loss: 0.1447 – acc: 0.9509 – val_loss: 0.0404 – val_acc: 0.9930
Epoch 25/100
10000/10000 [==============================] – 283s – loss: 0.1538 – acc: 0.9480 – val_loss: 0.0646 – val_acc: 0.9810
Epoch 26/100
10000/10000 [==============================] – 283s – loss: 0.1777 – acc: 0.9432 – val_loss: 0.0411 – val_acc: 0.9890
Epoch 27/100
10000/10000 [==============================] – 283s – loss: 0.1586 – acc: 0.9450 – val_loss: 0.0313 – val_acc: 0.9910
Epoch 28/100
10000/10000 [==============================] – 283s – loss: 0.1373 – acc: 0.9540 – val_loss: 0.0373 – val_acc: 0.9900
Epoch 29/100
10000/10000 [==============================] – 283s – loss: 0.1357 – acc: 0.9526 – val_loss: 0.0480 – val_acc: 0.9910
Epoch 30/100
10000/10000 [==============================] – 283s – loss: 0.1344 – acc: 0.9541 – val_loss: 0.0618 – val_acc: 0.9920
Epoch 31/100
10000/10000 [==============================] – 283s – loss: 0.1303 – acc: 0.9550 – val_loss: 0.0374 – val_acc: 0.9920
Epoch 32/100
10000/10000 [==============================] – 283s – loss: 0.1329 – acc: 0.9537 – val_loss: 0.0370 – val_acc: 0.9910
Epoch 33/100
10000/10000 [==============================] – 283s – loss: 0.1462 – acc: 0.9503 – val_loss: 0.0441 – val_acc: 0.9920
Epoch 34/100
10000/10000 [==============================] – 283s – loss: 0.1386 – acc: 0.9515 – val_loss: 0.0468 – val_acc: 0.9910
Epoch 35/100
10000/10000 [==============================] – 283s – loss: 0.1233 – acc: 0.9572 – val_loss: 0.0655 – val_acc: 0.9910
Epoch 36/100
10000/10000 [==============================] – 283s – loss: 0.1250 – acc: 0.9557 – val_loss: 0.0426 – val_acc: 0.9910
Epoch 37/100
10000/10000 [==============================] – 284s – loss: 0.1303 – acc: 0.9573 – val_loss: 0.0406 – val_acc: 0.9940
Epoch 38/100
10000/10000 [==============================] – 284s – loss: 0.1309 – acc: 0.9542 – val_loss: 0.0481 – val_acc: 0.9930
Epoch 39/100
10000/10000 [==============================] – 284s – loss: 0.1361 – acc: 0.9551 – val_loss: 0.0322 – val_acc: 0.9930
Epoch 40/100
10000/10000 [==============================] – 284s – loss: 0.1254 – acc: 0.9542 – val_loss: 0.0388 – val_acc: 0.9910
Epoch 41/100
10000/10000 [==============================] – 283s – loss: 0.1285 – acc: 0.9550 – val_loss: 0.0677 – val_acc: 0.9890
Epoch 42/100
10000/10000 [==============================] – 283s – loss: 0.1305 – acc: 0.9538 – val_loss: 0.0562 – val_acc: 0.9900
Epoch 43/100
10000/10000 [==============================] – 283s – loss: 0.1254 – acc: 0.9554 – val_loss: 0.0361 – val_acc: 0.9910
Epoch 44/100
10000/10000 [==============================] – 283s – loss: 0.1247 – acc: 0.9559 – val_loss: 0.0583 – val_acc: 0.9920
Epoch 45/100
10000/10000 [==============================] – 283s – loss: 0.1238 – acc: 0.9568 – val_loss: 0.0419 – val_acc: 0.9920
Epoch 46/100
10000/10000 [==============================] – 283s – loss: 0.1222 – acc: 0.9586 – val_loss: 0.0371 – val_acc: 0.9920
Epoch 47/100
10000/10000 [==============================] – 283s – loss: 0.1269 – acc: 0.9570 – val_loss: 0.0371 – val_acc: 0.9920
Epoch 48/100
10000/10000 [==============================] – 283s – loss: 0.1180 – acc: 0.9583 – val_loss: 0.0230 – val_acc: 0.9940
Epoch 49/100
10000/10000 [==============================] – 283s – loss: 0.1276 – acc: 0.9547 – val_loss: 0.0235 – val_acc: 0.9950
Epoch 50/100
10000/10000 [==============================] – 284s – loss: 0.1336 – acc: 0.9507 – val_loss: 0.0384 – val_acc: 0.9910
Epoch 51/100
10000/10000 [==============================] – 283s – loss: 0.1154 – acc: 0.9563 – val_loss: 0.0396 – val_acc: 0.9920
Epoch 52/100
10000/10000 [==============================] – 283s – loss: 0.1136 – acc: 0.9583 – val_loss: 0.0285 – val_acc: 0.9930
Epoch 53/100
10000/10000 [==============================] – 283s – loss: 0.1235 – acc: 0.9550 – val_loss: 0.0367 – val_acc: 0.9920
Epoch 54/100
10000/10000 [==============================] – 284s – loss: 0.1639 – acc: 0.9445 – val_loss: 0.0604 – val_acc: 0.9920
Epoch 55/100
10000/10000 [==============================] – 284s – loss: 0.1226 – acc: 0.9540 – val_loss: 0.0652 – val_acc: 0.9900
Epoch 56/100
10000/10000 [==============================] – 283s – loss: 0.1199 – acc: 0.9551 – val_loss: 0.0615 – val_acc: 0.9890
Epoch 57/100
10000/10000 [==============================] – 283s – loss: 0.1217 – acc: 0.9561 – val_loss: 0.0532 – val_acc: 0.9930
Epoch 58/100
10000/10000 [==============================] – 283s – loss: 0.1266 – acc: 0.9524 – val_loss: 0.0412 – val_acc: 0.9920
Epoch 59/100
10000/10000 [==============================] – 283s – loss: 0.1225 – acc: 0.9542 – val_loss: 0.0455 – val_acc: 0.9910
Epoch 60/100
10000/10000 [==============================] – 283s – loss: 0.1247 – acc: 0.9544 – val_loss: 0.0527 – val_acc: 0.9910
Epoch 61/100
10000/10000 [==============================] – 283s – loss: 0.1144 – acc: 0.9571 – val_loss: 0.0499 – val_acc: 0.9910
Epoch 62/100
10000/10000 [==============================] – 283s – loss: 0.1191 – acc: 0.9549 – val_loss: 0.0404 – val_acc: 0.9920
Epoch 63/100
10000/10000 [==============================] – 283s – loss: 0.1153 – acc: 0.9579 – val_loss: 0.0271 – val_acc: 0.9940
Epoch 64/100
10000/10000 [==============================] – 283s – loss: 0.1130 – acc: 0.9596 – val_loss: 0.0356 – val_acc: 0.9910
Epoch 65/100
10000/10000 [==============================] – 283s – loss: 0.1173 – acc: 0.9570 – val_loss: 0.0322 – val_acc: 0.9930
Epoch 66/100
10000/10000 [==============================] – 283s – loss: 0.1114 – acc: 0.9582 – val_loss: 0.0447 – val_acc: 0.9920
Epoch 67/100
10000/10000 [==============================] – 283s – loss: 0.1067 – acc: 0.9585 – val_loss: 0.0441 – val_acc: 0.9930
Epoch 68/100
10000/10000 [==============================] – 283s – loss: 0.1175 – acc: 0.9573 – val_loss: 0.0483 – val_acc: 0.9910
Epoch 69/100
10000/10000 [==============================] – 283s – loss: 0.1278 – acc: 0.9542 – val_loss: 0.0528 – val_acc: 0.9890
Epoch 70/100
10000/10000 [==============================] – 284s – loss: 0.1171 – acc: 0.9575 – val_loss: 0.0401 – val_acc: 0.9910
Epoch 71/100
10000/10000 [==============================] – 283s – loss: 0.1147 – acc: 0.9578 – val_loss: 0.0601 – val_acc: 0.9910
Epoch 72/100
10000/10000 [==============================] – 283s – loss: 0.1237 – acc: 0.9542 – val_loss: 0.0594 – val_acc: 0.9910
Epoch 73/100
10000/10000 [==============================] – 283s – loss: 0.1182 – acc: 0.9564 – val_loss: 0.0396 – val_acc: 0.9920
Epoch 74/100
10000/10000 [==============================] – 283s – loss: 0.1121 – acc: 0.9590 – val_loss: 0.0332 – val_acc: 0.9910
Epoch 75/100
10000/10000 [==============================] – 283s – loss: 0.1171 – acc: 0.9571 – val_loss: 0.0293 – val_acc: 0.9910
Epoch 76/100
10000/10000 [==============================] – 283s – loss: 0.1153 – acc: 0.9574 – val_loss: 0.0464 – val_acc: 0.9900
Epoch 77/100
10000/10000 [==============================] – 283s – loss: 0.1058 – acc: 0.9601 – val_loss: 0.0311 – val_acc: 0.9910
Epoch 78/100
10000/10000 [==============================] – 283s – loss: 0.1139 – acc: 0.9572 – val_loss: 0.0489 – val_acc: 0.9900
Epoch 79/100
10000/10000 [==============================] – 283s – loss: 0.1071 – acc: 0.9601 – val_loss: 0.0509 – val_acc: 0.9900
Epoch 80/100
10000/10000 [==============================] – 283s – loss: 0.1049 – acc: 0.9618 – val_loss: 0.0557 – val_acc: 0.9920
Epoch 81/100
10000/10000 [==============================] – 284s – loss: 0.1109 – acc: 0.9592 – val_loss: 0.0501 – val_acc: 0.9920
Epoch 82/100
10000/10000 [==============================] – 284s – loss: 0.1159 – acc: 0.9593 – val_loss: 0.0435 – val_acc: 0.9900
Epoch 83/100
10000/10000 [==============================] – 283s – loss: 0.1137 – acc: 0.9591 – val_loss: 0.0284 – val_acc: 0.9930
Epoch 84/100
10000/10000 [==============================] – 284s – loss: 0.1114 – acc: 0.9566 – val_loss: 0.0393 – val_acc: 0.9900
Epoch 85/100
10000/10000 [==============================] – 284s – loss: 0.1057 – acc: 0.9602 – val_loss: 0.0396 – val_acc: 0.9920
Epoch 86/100
10000/10000 [==============================] – 284s – loss: 0.1147 – acc: 0.9606 – val_loss: 0.0426 – val_acc: 0.9890
Epoch 87/100
10000/10000 [==============================] – 284s – loss: 0.1142 – acc: 0.9570 – val_loss: 0.0327 – val_acc: 0.9920
Epoch 88/100
10000/10000 [==============================] – 284s – loss: 0.1092 – acc: 0.9592 – val_loss: 0.0295 – val_acc: 0.9920
Epoch 89/100
10000/10000 [==============================] – 284s – loss: 0.1121 – acc: 0.9588 – val_loss: 0.0295 – val_acc: 0.9940
Epoch 90/100
10000/10000 [==============================] – 284s – loss: 0.1082 – acc: 0.9610 – val_loss: 0.0423 – val_acc: 0.9930
Epoch 91/100
10000/10000 [==============================] – 284s – loss: 0.1028 – acc: 0.9617 – val_loss: 0.0374 – val_acc: 0.9930
Epoch 92/100
10000/10000 [==============================] – 284s – loss: 0.1095 – acc: 0.9612 – val_loss: 0.0410 – val_acc: 0.9920
Epoch 93/100
10000/10000 [==============================] – 284s – loss: 0.1073 – acc: 0.9619 – val_loss: 0.0321 – val_acc: 0.9940
Epoch 94/100
10000/10000 [==============================] – 284s – loss: 0.1187 – acc: 0.9570 – val_loss: 0.0492 – val_acc: 0.9930
Epoch 95/100
10000/10000 [==============================] – 284s – loss: 0.1125 – acc: 0.9577 – val_loss: 0.0597 – val_acc: 0.9930
Epoch 96/100
10000/10000 [==============================] – 284s – loss: 0.1057 – acc: 0.9602 – val_loss: 0.0451 – val_acc: 0.9920
Epoch 97/100
10000/10000 [==============================] – 283s – loss: 0.1047 – acc: 0.9600 – val_loss: 0.0460 – val_acc: 0.9930
Epoch 98/100
10000/10000 [==============================] – 284s – loss: 0.1155 – acc: 0.9559 – val_loss: 0.0626 – val_acc: 0.9900
Epoch 99/100
10000/10000 [==============================] – 284s – loss: 0.1166 – acc: 0.9563 – val_loss: 0.0354 – val_acc: 0.9930
Epoch 100/100
10000/10000 [==============================] – 284s – loss: 0.1087 – acc: 0.9596 – val_loss: 0.0300 – val_acc: 0.9930

# Train overnight, let's save it.          
model.save( 'traffic_signs.h5' )

from keras.models import load_model
model = load_model('traffic_signs.h5')
predictions_test = model.evaluate(X_test, y_test, batch_size=32, verbose=1)

[0.058963652333059884, 0.99144893111638954]

loss 0.0589, accuracy 99.144% This is right.

# See those predictions that are wrong 
predicted_y = np.argmax(model.predict(X_test, batch_size= 32 , verbose= 1 ), axis= 1 )
 groundtruth_y = np.argmax (y_test, axis= 1 )
 diff_idx = np.equal( np.array(predicted_y), ( np.array(groundtruth_y)))

predicted_y[diff_idx == False]
groundtruth_y[diff_idx == False]

Therefore, it is correct to use 32*32 and a relatively small network for training in the project. It is indeed very troublesome to use a large network, especially if there are no machines that can be used.

If you continue to optimize, you can also use other train data, but training takes one night at a time, so I don’t play. Of course, picture augments can also be messed up, and it should be helpful to see some examples of misclassification.

You may also like...

Leave a Reply

Your email address will not be published.