使用Colab来加速Donkey Car训练 (Tensorflow GPU)

(本文来自robocarstore.cn) 本notebook助你快速训练你的Donkey car或者自动驾驶小车模型。

参考并改进了@sachindroid8的notebook,先向前人致敬!

先说说使用Colab进行训练的优缺点

1. 效率 使用Colab需要梯子,也要把数据传给google,上传时间因人而异,我上传大概花来2-3分钟,剩下就是执行代码和训练。第一执行代码需要搞懂什么原理,后面执行基本不用花什么时间,然而使用GPU训练时间,我有6k图片,训练30-40个Epoch左右提前结束,训练时间少于1分钟!每个Epoch只需1-2秒。 然后使用我的Macbook Pro训练,因为没有GPU的缘故,每个Epoc需要30-50秒,训练下来,接近40分钟到1小时才能完成。

2. 便利性 如果没有梯子,当然Colab不是一个选择,我知道百度也提供一些有限度免费的服务器,以后可以再做测试,但有梯子的话,Google Colab是最好的选择。

下面便开始教你怎样开始训练
 

载入我的Notebook

 
 

安装 TensorFlow 1.14.0

TensorFlow 2.x和Donkey Car 3.x现在还有兼容性问题,暂时不推荐使用(2019.8.17)

In [1]:
!pip install tensorflow-gpu==1.14.0
 
Collecting tensorflow-gpu==1.14.0
  Downloading https://files.pythonhosted.org/packages/76/04/43153bfdfcf6c9a4c38ecdb971ca9a75b9a791bb69a764d652c359aca504/tensorflow_gpu-1.14.0-cp36-cp36m-manylinux1_x86_64.whl (377.0MB)
     |████████████████████████████████| 377.0MB 86kB/s 
Requirement already satisfied: grpcio>=1.8.6 in /usr/local/lib/python3.6/dist-packages (from tensorflow-gpu==1.14.0) (1.15.0)
Requirement already satisfied: absl-py>=0.7.0 in /usr/local/lib/python3.6/dist-packages (from tensorflow-gpu==1.14.0) (0.7.1)
Requirement already satisfied: tensorflow-estimator<1.15.0rc0,>=1.14.0rc0 in /usr/local/lib/python3.6/dist-packages (from tensorflow-gpu==1.14.0) (1.14.0)
Requirement already satisfied: wrapt>=1.11.1 in /usr/local/lib/python3.6/dist-packages (from tensorflow-gpu==1.14.0) (1.11.2)
Requirement already satisfied: termcolor>=1.1.0 in /usr/local/lib/python3.6/dist-packages (from tensorflow-gpu==1.14.0) (1.1.0)
Requirement already satisfied: astor>=0.6.0 in /usr/local/lib/python3.6/dist-packages (from tensorflow-gpu==1.14.0) (0.8.0)
Requirement already satisfied: keras-applications>=1.0.6 in /usr/local/lib/python3.6/dist-packages (from tensorflow-gpu==1.14.0) (1.0.8)
Requirement already satisfied: tensorboard<1.15.0,>=1.14.0 in /usr/local/lib/python3.6/dist-packages (from tensorflow-gpu==1.14.0) (1.14.0)
Requirement already satisfied: wheel>=0.26 in /usr/local/lib/python3.6/dist-packages (from tensorflow-gpu==1.14.0) (0.33.4)
Requirement already satisfied: protobuf>=3.6.1 in /usr/local/lib/python3.6/dist-packages (from tensorflow-gpu==1.14.0) (3.7.1)
Requirement already satisfied: six>=1.10.0 in /usr/local/lib/python3.6/dist-packages (from tensorflow-gpu==1.14.0) (1.12.0)
Requirement already satisfied: keras-preprocessing>=1.0.5 in /usr/local/lib/python3.6/dist-packages (from tensorflow-gpu==1.14.0) (1.1.0)
Requirement already satisfied: google-pasta>=0.1.6 in /usr/local/lib/python3.6/dist-packages (from tensorflow-gpu==1.14.0) (0.1.7)
Requirement already satisfied: gast>=0.2.0 in /usr/local/lib/python3.6/dist-packages (from tensorflow-gpu==1.14.0) (0.2.2)
Requirement already satisfied: numpy<2.0,>=1.14.5 in /usr/local/lib/python3.6/dist-packages (from tensorflow-gpu==1.14.0) (1.16.4)
Requirement already satisfied: h5py in /usr/local/lib/python3.6/dist-packages (from keras-applications>=1.0.6->tensorflow-gpu==1.14.0) (2.8.0)
Requirement already satisfied: markdown>=2.6.8 in /usr/local/lib/python3.6/dist-packages (from tensorboard<1.15.0,>=1.14.0->tensorflow-gpu==1.14.0) (3.1.1)
Requirement already satisfied: werkzeug>=0.11.15 in /usr/local/lib/python3.6/dist-packages (from tensorboard<1.15.0,>=1.14.0->tensorflow-gpu==1.14.0) (0.15.5)
Requirement already satisfied: setuptools>=41.0.0 in /usr/local/lib/python3.6/dist-packages (from tensorboard<1.15.0,>=1.14.0->tensorflow-gpu==1.14.0) (41.0.1)
Installing collected packages: tensorflow-gpu
Successfully installed tensorflow-gpu-1.14.0
 

检查GPU是否有效

如果显示”Found GPU at: / device: GPU: 0“,则GPU可以正常使用 如果没有以上输出,需要检查Runtime (运行类型)是否选择了GPU硬件加速器

In [2]:
import tensorflow as tf
device_name = tf.test.gpu_device_name()
if device_name != '/device:GPU:0':
  raise SystemError('GPU device not found')
print('Found GPU at: {}'.format(device_name))
 
Found GPU at: /device:GPU:0
 

克隆Donkey respository

In [3]:
!git clone https://github.com/autorope/donkeycar.git donkey
 
Cloning into 'donkey'...
remote: Enumerating objects: 120, done.
remote: Counting objects: 100% (120/120), done.
remote: Compressing objects: 100% (76/76), done.
remote: Total 10558 (delta 65), reused 73 (delta 31), pack-reused 10438
Receiving objects: 100% (10558/10558), 58.74 MiB | 46.70 MiB/s, done.
Resolving deltas: 100% (6528/6528), done.
 

安装 Donkey car

In [4]:
!pip3 install -e donkey
 
Obtaining file:///content/donkey
Requirement already satisfied: numpy in /usr/local/lib/python3.6/dist-packages (from donkeycar==3.1.0) (1.16.4)
Requirement already satisfied: pillow in /usr/local/lib/python3.6/dist-packages (from donkeycar==3.1.0) (4.3.0)
Requirement already satisfied: docopt in /usr/local/lib/python3.6/dist-packages (from donkeycar==3.1.0) (0.6.2)
Requirement already satisfied: tornado in /usr/local/lib/python3.6/dist-packages (from donkeycar==3.1.0) (4.5.3)
Requirement already satisfied: requests in /usr/local/lib/python3.6/dist-packages (from donkeycar==3.1.0) (2.21.0)
Requirement already satisfied: h5py in /usr/local/lib/python3.6/dist-packages (from donkeycar==3.1.0) (2.8.0)
Requirement already satisfied: moviepy in /usr/local/lib/python3.6/dist-packages (from donkeycar==3.1.0) (0.2.3.5)
Requirement already satisfied: pandas in /usr/local/lib/python3.6/dist-packages (from donkeycar==3.1.0) (0.24.2)
Requirement already satisfied: PrettyTable in /usr/local/lib/python3.6/dist-packages (from donkeycar==3.1.0) (0.7.2)
Collecting paho-mqtt (from donkeycar==3.1.0)
  Downloading https://files.pythonhosted.org/packages/25/63/db25e62979c2a716a74950c9ed658dce431b5cb01fde29eb6cba9489a904/paho-mqtt-1.4.0.tar.gz (88kB)
     |████████████████████████████████| 92kB 4.2MB/s 
Requirement already satisfied: olefile in /usr/local/lib/python3.6/dist-packages (from pillow->donkeycar==3.1.0) (0.46)
Requirement already satisfied: urllib3<1.25,>=1.21.1 in /usr/local/lib/python3.6/dist-packages (from requests->donkeycar==3.1.0) (1.24.3)
Requirement already satisfied: certifi>=2017.4.17 in /usr/local/lib/python3.6/dist-packages (from requests->donkeycar==3.1.0) (2019.6.16)
Requirement already satisfied: chardet<3.1.0,>=3.0.2 in /usr/local/lib/python3.6/dist-packages (from requests->donkeycar==3.1.0) (3.0.4)
Requirement already satisfied: idna<2.9,>=2.5 in /usr/local/lib/python3.6/dist-packages (from requests->donkeycar==3.1.0) (2.8)
Requirement already satisfied: six in /usr/local/lib/python3.6/dist-packages (from h5py->donkeycar==3.1.0) (1.12.0)
Requirement already satisfied: decorator<5.0,>=4.0.2 in /usr/local/lib/python3.6/dist-packages (from moviepy->donkeycar==3.1.0) (4.4.0)
Requirement already satisfied: tqdm<5.0,>=4.11.2 in /usr/local/lib/python3.6/dist-packages (from moviepy->donkeycar==3.1.0) (4.28.1)
Requirement already satisfied: imageio<3.0,>=2.1.2 in /usr/local/lib/python3.6/dist-packages (from moviepy->donkeycar==3.1.0) (2.4.1)
Requirement already satisfied: pytz>=2011k in /usr/local/lib/python3.6/dist-packages (from pandas->donkeycar==3.1.0) (2018.9)
Requirement already satisfied: python-dateutil>=2.5.0 in /usr/local/lib/python3.6/dist-packages (from pandas->donkeycar==3.1.0) (2.5.3)
Building wheels for collected packages: paho-mqtt
  Building wheel for paho-mqtt (setup.py) ... done
  Created wheel for paho-mqtt: filename=paho_mqtt-1.4.0-cp36-none-any.whl size=48333 sha256=9a67d0c95fae2b9495c20980895d9569ef53859cbc22bb57fc2466d7a581af7b
  Stored in directory: /root/.cache/pip/wheels/82/e5/de/d90d0f397648a1b58ffeea1b5742ac8c77f71fd43b550fa5a5
Successfully built paho-mqtt
Installing collected packages: paho-mqtt, donkeycar
  Running setup.py develop for donkeycar
Successfully installed donkeycar paho-mqtt-1.4.0
 

创建项目

我使用了mycar作为项目名称,你可以改名,但改名后需要相应修改后面但代码

In [5]:
!donkey createcar --path /content/mycar
using donkey v3.1.0 ...
Creating car folder: /content/mycar
making dir  /content/mycar
Creating data & model folders.
making dir  /content/mycar/models
making dir  /content/mycar/data
making dir  /content/mycar/logs
Copying car application template: complete
Copying car config defaults. Adjust these before starting your car.
Copying train script. Adjust these before starting your car.
Copying my car config overrides
Donkey setup complete.
 

准备数据: 上传data.zip并解压

现在你需要把pi采集回来的data目录上需要训练的目录打包,保存成data.zip. 在pi的data目录上运行:

$ zip -r data.zip tub_3_19-08-17/

然后拷贝会电脑,准备上传到Colab

上传data.zip到Colab

运行下面代码,会出现一个上传按钮,点击上传刚才打包的data.zip

In [7]:
import os
from google.colab import files

if(os.path.exists("/content/data.zip")):
   os.remove("/content/data.zip")
if(os.path.exists("/content/mycar/data/data.zip")):
   os.remove("/content/mycar/data/data.zip")
   
uploaded = files.upload()

WORK_FOLDER = "/content/mycar/data/"
if(os.path.exists(WORK_FOLDER) == False):
  os.makedirs(WORK_FOLDER)

!mv /content/data.zip /content/mycar/data/
%cd /content/mycar/data/
!unzip -o data.zip
 
  

清理已经上传的文件

你需要确保content/mycar/data目录下有tub目录,目录里面有图片和对应的json文件 data.zip就不用保留了

In [0]:
!rm /content/mycar/data/data.zip
 

训练模型

In [21]:
!python /content/mycar/manage.py train --model /content/mycar/models/mypilot.h5
using donkey v3.1.0 ...
loading config file: /content/mycar/config.py
loading personal config over-rides

config loaded
WARNING: Logging before flag parsing goes to stderr.
W0818 04:53:15.944086 140399927523200 deprecation_wrapper.py:119] From /content/donkey/donkeycar/parts/keras.py:18: The name tf.ConfigProto is deprecated. Please use tf.compat.v1.ConfigProto instead.

W0818 04:53:15.944333 140399927523200 deprecation_wrapper.py:119] From /content/donkey/donkeycar/parts/keras.py:18: The name tf.Session is deprecated. Please use tf.compat.v1.Session instead.

2019-08-18 04:53:15.954857: I tensorflow/core/platform/cpu_feature_guard.cc:142] Your CPU supports instructions that this TensorFlow binary was not compiled to use: AVX2 FMA
2019-08-18 04:53:15.959505: I tensorflow/stream_executor/platform/default/dso_loader.cc:42] Successfully opened dynamic library libcuda.so.1
2019-08-18 04:53:16.083690: I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:1005] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero
2019-08-18 04:53:16.084227: I tensorflow/compiler/xla/service/service.cc:168] XLA service 0x2455100 executing computations on platform CUDA. Devices:
2019-08-18 04:53:16.084262: I tensorflow/compiler/xla/service/service.cc:175]   StreamExecutor device (0): Tesla T4, Compute Capability 7.5
2019-08-18 04:53:16.086194: I tensorflow/core/platform/profile_utils/cpu_utils.cc:94] CPU Frequency: 2300000000 Hz
2019-08-18 04:53:16.086460: I tensorflow/compiler/xla/service/service.cc:168] XLA service 0x65e6380 executing computations on platform Host. Devices:
2019-08-18 04:53:16.086508: I tensorflow/compiler/xla/service/service.cc:175]   StreamExecutor device (0): <undefined>, <undefined>
2019-08-18 04:53:16.086686: I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:1005] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero
2019-08-18 04:53:16.087039: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1640] Found device 0 with properties: 
name: Tesla T4 major: 7 minor: 5 memoryClockRate(GHz): 1.59
pciBusID: 0000:00:04.0
2019-08-18 04:53:16.087321: I tensorflow/stream_executor/platform/default/dso_loader.cc:42] Successfully opened dynamic library libcudart.so.10.0
2019-08-18 04:53:16.088548: I tensorflow/stream_executor/platform/default/dso_loader.cc:42] Successfully opened dynamic library libcublas.so.10.0
2019-08-18 04:53:16.089621: I tensorflow/stream_executor/platform/default/dso_loader.cc:42] Successfully opened dynamic library libcufft.so.10.0
2019-08-18 04:53:16.089935: I tensorflow/stream_executor/platform/default/dso_loader.cc:42] Successfully opened dynamic library libcurand.so.10.0
2019-08-18 04:53:16.091399: I tensorflow/stream_executor/platform/default/dso_loader.cc:42] Successfully opened dynamic library libcusolver.so.10.0
2019-08-18 04:53:16.092394: I tensorflow/stream_executor/platform/default/dso_loader.cc:42] Successfully opened dynamic library libcusparse.so.10.0
2019-08-18 04:53:16.095470: I tensorflow/stream_executor/platform/default/dso_loader.cc:42] Successfully opened dynamic library libcudnn.so.7
2019-08-18 04:53:16.095606: I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:1005] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero
2019-08-18 04:53:16.096009: I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:1005] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero
2019-08-18 04:53:16.096350: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1763] Adding visible gpu devices: 0
2019-08-18 04:53:16.096401: I tensorflow/stream_executor/platform/default/dso_loader.cc:42] Successfully opened dynamic library libcudart.so.10.0
2019-08-18 04:53:16.097166: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1181] Device interconnect StreamExecutor with strength 1 edge matrix:
2019-08-18 04:53:16.097190: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1187]      0 
2019-08-18 04:53:16.097201: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1200] 0:   N 
2019-08-18 04:53:16.097482: I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:1005] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero
2019-08-18 04:53:16.097878: I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:1005] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero
2019-08-18 04:53:16.098226: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1326] Created TensorFlow device (/job:localhost/replica:0/task:0/device:GPU:0 with 14089 MB memory) -> physical GPU (device: 0, name: Tesla T4, pci bus id: 0000:00:04.0, compute capability: 7.5)
"get_model_by_type" model Type is: linear
W0818 04:53:16.444941 140399927523200 deprecation.py:506] From /usr/local/lib/python3.6/dist-packages/tensorflow/python/ops/init_ops.py:1251: calling VarianceScaling.__init__ (from tensorflow.python.ops.init_ops) with dtype is deprecated and will be removed in a future version.
Instructions for updating:
Call initializer instance with the dtype argument instead of passing it to the constructor
training with model type <class 'donkeycar.parts.keras.KerasLinear'>
Model: "model"
__________________________________________________________________________________________________
Layer (type)                    Output Shape         Param #     Connected to                     
==================================================================================================
img_in (InputLayer)             [(None, 120, 160, 3) 0                                            
__________________________________________________________________________________________________
conv2d_1 (Conv2D)               (None, 58, 78, 24)   1824        img_in[0][0]                     
__________________________________________________________________________________________________
dropout (Dropout)               (None, 58, 78, 24)   0           conv2d_1[0][0]                   
__________________________________________________________________________________________________
conv2d_2 (Conv2D)               (None, 27, 37, 32)   19232       dropout[0][0]                    
__________________________________________________________________________________________________
dropout_1 (Dropout)             (None, 27, 37, 32)   0           conv2d_2[0][0]                   
__________________________________________________________________________________________________
conv2d_3 (Conv2D)               (None, 12, 17, 64)   51264       dropout_1[0][0]                  
__________________________________________________________________________________________________
dropout_2 (Dropout)             (None, 12, 17, 64)   0           conv2d_3[0][0]                   
__________________________________________________________________________________________________
conv2d_4 (Conv2D)               (None, 10, 15, 64)   36928       dropout_2[0][0]                  
__________________________________________________________________________________________________
dropout_3 (Dropout)             (None, 10, 15, 64)   0           conv2d_4[0][0]                   
__________________________________________________________________________________________________
conv2d_5 (Conv2D)               (None, 8, 13, 64)    36928       dropout_3[0][0]                  
__________________________________________________________________________________________________
dropout_4 (Dropout)             (None, 8, 13, 64)    0           conv2d_5[0][0]                   
__________________________________________________________________________________________________
flattened (Flatten)             (None, 6656)         0           dropout_4[0][0]                  
__________________________________________________________________________________________________
dense (Dense)                   (None, 100)          665700      flattened[0][0]                  
__________________________________________________________________________________________________
dropout_5 (Dropout)             (None, 100)          0           dense[0][0]                      
__________________________________________________________________________________________________
dense_1 (Dense)                 (None, 50)           5050        dropout_5[0][0]                  
__________________________________________________________________________________________________
dropout_6 (Dropout)             (None, 50)           0           dense_1[0][0]                    
__________________________________________________________________________________________________
n_outputs0 (Dense)              (None, 1)            51          dropout_6[0][0]                  
__________________________________________________________________________________________________
n_outputs1 (Dense)              (None, 1)            51          dropout_6[0][0]                  
==================================================================================================
Total params: 817,028
Trainable params: 817,028
Non-trainable params: 0
__________________________________________________________________________________________________
None
found 0 pickles writing json records and images in tub /content/mycar/data/tub_3_19-08-17
/content/mycar/data/tub_3_19-08-17
collating 5799 records ...
train: 4639, val: 1160
total records: 5799
steps_per_epoch 36
Epoch 1/100
2019-08-18 04:53:19.663907: I tensorflow/stream_executor/platform/default/dso_loader.cc:42] Successfully opened dynamic library libcublas.so.10.0
2019-08-18 04:53:19.984999: I tensorflow/stream_executor/platform/default/dso_loader.cc:42] Successfully opened dynamic library libcudnn.so.7
35/36 [============================>.] - ETA: 0s - loss: 0.1681 - n_outputs0_loss: 0.1555 - n_outputs1_loss: 0.0126
Epoch 00001: val_loss improved from inf to 0.14482, saving model to /content/mycar/models/mypilot.h5
36/36 [==============================] - 8s 213ms/step - loss: 0.1677 - n_outputs0_loss: 0.1553 - n_outputs1_loss: 0.0124 - val_loss: 0.1448 - val_n_outputs0_loss: 0.1409 - val_n_outputs1_loss: 0.0039
Epoch 2/100
34/36 [===========================>..] - ETA: 0s - loss: 0.1278 - n_outputs0_loss: 0.1234 - n_outputs1_loss: 0.0044
Epoch 00002: val_loss improved from 0.14482 to 0.08814, saving model to /content/mycar/models/mypilot.h5
36/36 [==============================] - 2s 53ms/step - loss: 0.1257 - n_outputs0_loss: 0.1214 - n_outputs1_loss: 0.0043 - val_loss: 0.0881 - val_n_outputs0_loss: 0.0870 - val_n_outputs1_loss: 0.0012
Epoch 3/100
35/36 [============================>.] - ETA: 0s - loss: 0.0943 - n_outputs0_loss: 0.0910 - n_outputs1_loss: 0.0033
Epoch 00003: val_loss improved from 0.08814 to 0.07490, saving model to /content/mycar/models/mypilot.h5
36/36 [==============================] - 2s 52ms/step - loss: 0.0938 - n_outputs0_loss: 0.0905 - n_outputs1_loss: 0.0033 - val_loss: 0.0749 - val_n_outputs0_loss: 0.0738 - val_n_outputs1_loss: 0.0011
Epoch 4/100
35/36 [============================>.] - ETA: 0s - loss: 0.0840 - n_outputs0_loss: 0.0813 - n_outputs1_loss: 0.0027
Epoch 00004: val_loss improved from 0.07490 to 0.07108, saving model to /content/mycar/models/mypilot.h5
36/36 [==============================] - 2s 51ms/step - loss: 0.0835 - n_outputs0_loss: 0.0808 - n_outputs1_loss: 0.0027 - val_loss: 0.0711 - val_n_outputs0_loss: 0.0702 - val_n_outputs1_loss: 8.9668e-04
Epoch 5/100
35/36 [============================>.] - ETA: 0s - loss: 0.0767 - n_outputs0_loss: 0.0741 - n_outputs1_loss: 0.0026
Epoch 00005: val_loss did not improve from 0.07108
36/36 [==============================] - 2s 50ms/step - loss: 0.0765 - n_outputs0_loss: 0.0739 - n_outputs1_loss: 0.0026 - val_loss: 0.0722 - val_n_outputs0_loss: 0.0717 - val_n_outputs1_loss: 5.4629e-04
Epoch 6/100
35/36 [============================>.] - ETA: 0s - loss: 0.0750 - n_outputs0_loss: 0.0727 - n_outputs1_loss: 0.0023
Epoch 00006: val_loss improved from 0.07108 to 0.06483, saving model to /content/mycar/models/mypilot.h5
36/36 [==============================] - 2s 52ms/step - loss: 0.0749 - n_outputs0_loss: 0.0725 - n_outputs1_loss: 0.0024 - val_loss: 0.0648 - val_n_outputs0_loss: 0.0641 - val_n_outputs1_loss: 7.5336e-04
Epoch 7/100
35/36 [============================>.] - ETA: 0s - loss: 0.0711 - n_outputs0_loss: 0.0689 - n_outputs1_loss: 0.0022
Epoch 00007: val_loss improved from 0.06483 to 0.06324, saving model to /content/mycar/models/mypilot.h5
36/36 [==============================] - 2s 52ms/step - loss: 0.0711 - n_outputs0_loss: 0.0689 - n_outputs1_loss: 0.0021 - val_loss: 0.0632 - val_n_outputs0_loss: 0.0626 - val_n_outputs1_loss: 5.9058e-04
Epoch 8/100
35/36 [============================>.] - ETA: 0s - loss: 0.0693 - n_outputs0_loss: 0.0675 - n_outputs1_loss: 0.0018
Epoch 00008: val_loss did not improve from 0.06324
36/36 [==============================] - 2s 51ms/step - loss: 0.0690 - n_outputs0_loss: 0.0672 - n_outputs1_loss: 0.0018 - val_loss: 0.0644 - val_n_outputs0_loss: 0.0637 - val_n_outputs1_loss: 7.8261e-04
Epoch 9/100
35/36 [============================>.] - ETA: 0s - loss: 0.0693 - n_outputs0_loss: 0.0675 - n_outputs1_loss: 0.0018
Epoch 00009: val_loss did not improve from 0.06324
36/36 [==============================] - 2s 50ms/step - loss: 0.0690 - n_outputs0_loss: 0.0672 - n_outputs1_loss: 0.0018 - val_loss: 0.0653 - val_n_outputs0_loss: 0.0646 - val_n_outputs1_loss: 6.6657e-04
Epoch 10/100
34/36 [===========================>..] - ETA: 0s - loss: 0.0651 - n_outputs0_loss: 0.0633 - n_outputs1_loss: 0.0018
Epoch 00010: val_loss did not improve from 0.06324
36/36 [==============================] - 2s 51ms/step - loss: 0.0657 - n_outputs0_loss: 0.0639 - n_outputs1_loss: 0.0018 - val_loss: 0.0699 - val_n_outputs0_loss: 0.0692 - val_n_outputs1_loss: 6.9729e-04
Epoch 11/100
35/36 [============================>.] - ETA: 0s - loss: 0.0630 - n_outputs0_loss: 0.0612 - n_outputs1_loss: 0.0018
Epoch 00011: val_loss did not improve from 0.06324
36/36 [==============================] - 2s 51ms/step - loss: 0.0630 - n_outputs0_loss: 0.0612 - n_outputs1_loss: 0.0018 - val_loss: 0.0633 - val_n_outputs0_loss: 0.0619 - val_n_outputs1_loss: 0.0014
Epoch 12/100
35/36 [============================>.] - ETA: 0s - loss: 0.0643 - n_outputs0_loss: 0.0626 - n_outputs1_loss: 0.0016
Epoch 00012: val_loss improved from 0.06324 to 0.06034, saving model to /content/mycar/models/mypilot.h5
36/36 [==============================] - 2s 52ms/step - loss: 0.0644 - n_outputs0_loss: 0.0628 - n_outputs1_loss: 0.0017 - val_loss: 0.0603 - val_n_outputs0_loss: 0.0598 - val_n_outputs1_loss: 4.9525e-04
Epoch 13/100
35/36 [============================>.] - ETA: 0s - loss: 0.0611 - n_outputs0_loss: 0.0597 - n_outputs1_loss: 0.0014
Epoch 00013: val_loss improved from 0.06034 to 0.05636, saving model to /content/mycar/models/mypilot.h5
36/36 [==============================] - 2s 52ms/step - loss: 0.0613 - n_outputs0_loss: 0.0599 - n_outputs1_loss: 0.0014 - val_loss: 0.0564 - val_n_outputs0_loss: 0.0557 - val_n_outputs1_loss: 6.3083e-04
Epoch 14/100
34/36 [===========================>..] - ETA: 0s - loss: 0.0593 - n_outputs0_loss: 0.0580 - n_outputs1_loss: 0.0013
Epoch 00014: val_loss did not improve from 0.05636
36/36 [==============================] - 2s 51ms/step - loss: 0.0590 - n_outputs0_loss: 0.0577 - n_outputs1_loss: 0.0013 - val_loss: 0.0580 - val_n_outputs0_loss: 0.0575 - val_n_outputs1_loss: 5.4033e-04
Epoch 15/100
34/36 [===========================>..] - ETA: 0s - loss: 0.0552 - n_outputs0_loss: 0.0540 - n_outputs1_loss: 0.0012
Epoch 00015: val_loss did not improve from 0.05636
36/36 [==============================] - 2s 51ms/step - loss: 0.0555 - n_outputs0_loss: 0.0542 - n_outputs1_loss: 0.0012 - val_loss: 0.0565 - val_n_outputs0_loss: 0.0559 - val_n_outputs1_loss: 5.6679e-04
Epoch 16/100
35/36 [============================>.] - ETA: 0s - loss: 0.0538 - n_outputs0_loss: 0.0527 - n_outputs1_loss: 0.0012
Epoch 00016: val_loss did not improve from 0.05636
36/36 [==============================] - 2s 50ms/step - loss: 0.0538 - n_outputs0_loss: 0.0526 - n_outputs1_loss: 0.0012 - val_loss: 0.0624 - val_n_outputs0_loss: 0.0619 - val_n_outputs1_loss: 5.0014e-04
Epoch 17/100
35/36 [============================>.] - ETA: 0s - loss: 0.0536 - n_outputs0_loss: 0.0525 - n_outputs1_loss: 0.0011
Epoch 00017: val_loss improved from 0.05636 to 0.05615, saving model to /content/mycar/models/mypilot.h5
36/36 [==============================] - 2s 53ms/step - loss: 0.0534 - n_outputs0_loss: 0.0523 - n_outputs1_loss: 0.0011 - val_loss: 0.0561 - val_n_outputs0_loss: 0.0556 - val_n_outputs1_loss: 5.2067e-04
Epoch 18/100
35/36 [============================>.] - ETA: 0s - loss: 0.0502 - n_outputs0_loss: 0.0492 - n_outputs1_loss: 0.0011
Epoch 00018: val_loss improved from 0.05615 to 0.05594, saving model to /content/mycar/models/mypilot.h5
36/36 [==============================] - 2s 52ms/step - loss: 0.0501 - n_outputs0_loss: 0.0490 - n_outputs1_loss: 0.0011 - val_loss: 0.0559 - val_n_outputs0_loss: 0.0555 - val_n_outputs1_loss: 4.4089e-04
Epoch 00018: early stopping
Training completed in 0:00:40.


----------- Best Eval Loss :0.055939 ---------
<Figure size 640x480 with 1 Axes>
 

显示训练结果的Loss曲线

In [26]:
import matplotlib.pyplot as plt
import cv2
import glob
import os

list_of_png = glob.glob('/content/mycar/models/*png')
latest_png = max(list_of_png, key=os.path.getctime)

image = cv2.imread(latest_png)
plt.imshow(image)
 
/content/mycar/models/mypilot.h5_loss_acc_0.055939.png
Out[26]:
<matplotlib.image.AxesImage at 0x7f867c896be0>
 
 

将训练好的模型放回 Donkey Car.

一旦模型训练完毕,你可以在 mycar/models中找到训练好的模型 1.下载mypilot文件到你到PC或Mac 2. 再从PC或Mac拷贝模型到你到pi

最后用Autopilot mode来驾驶Donkey car

Enjoy!

修复VI上的方向键失效

vi已经老了?大量易用替代工具都能做好文本编辑,但对应早已熟悉vi的各种快捷键的人来说,vi还是一个快捷方便的选择。

但在某些linux系统下,vi的方向键老是不好使,现象是在编辑状态上按方向键,然后马上换行,并不出现一些莫名其妙的字符。

经查证后,可以增加一个~/.exrc文件

set nocompatible

在Mac上安装Python 3.7

安装Python 3.7,可以在Python的官方网址安装,但如果使用安装包管理工具Homebrew来安装,安装过程就会轻松很多。这篇文章就是介绍用Homebrew来安装python 3.7,其中所有代码都在Jupyter Notebook下运行, 最后也会附上notebook的附件。

查看现在的Python版本

如果Python 2预先安装在你的Mac,你可以用以下命令来检查现在的Python版本

python --version

如果要检查一下Python 3是不是已经预先安装来,可以用python3 –version来检查Python的版本

python3 --version

安装XCode和Homebrew

要方便地安装Python3,可以使用Homebrew安装包管理器。但是安装Homebrew需要先安装苹果地xcode包,可以按照以下命令进行安装。安装xcode和相关依赖需要较长时间,需要点耐心。

xcode-select --install
 安装好xcode后,可以开始安装Homebrew
/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"

以上命令可以在Homebrew主页找到, 一句命令就能完成安装。

测试Homebrew是否已经安装好,可以运行以下命令.

brew doctor

安装Python 3

可以开始安装Python 3了,现在运行以下命令:

brew install python3

安装完成后可以通过以下命令来检查版本信息

python3 --version

现在可以在Mac终端打开一个Python 3终端(注意:如果直接在Jupyter上就会hang在那里)

python3

如果要退出终端,你可以输入exit()或者通过快捷键ctrl-D。如果你想继续使用Python 2,可以继续通过python命令来打开。

python

创建虚拟环境Virtual Environment

虚拟环境的好处是你可以为不同项目建立一个独立的环境,你可以在同一台电脑用venv轻易切换Python 2.7和Python 3.7的版本。

一个比较好的习惯就是把不同虚拟环境放到home目录。

mkdir ~/.virtualenvs

现在可以建立一个叫myvenv的虚拟环境

python3 -m venv ~/.virtualenvs/myvenv

这里用了python3来建立虚拟环境所以在虚拟环境里面输入pyhton就默认使用来python3,而不是Python 2.

通过以下命令,我们就能激活环境

source ~/.virtualenvs/myvenv/bin/activate
在环境里,你可以通过命令 pip freeze 来检查虚拟环境里面安装来什么包。

要终止虚拟环境,可以通过deactivate命令来结束

deactivate

Jetson Nano介绍

英伟达的 Jetson Nano是一块用于深度学习或者计算机视觉的开发板,板子整合了128核Maxwell GPU,四核ARM A57 64-bit CPU和4G LPDDR4内存,也支持MIPI CSI-2接口摄像头和PCIe Gen2 高速I/O(用来接无线网卡)。

Jetson Nano运行在Linux (Ubuntu) 上,可以处理472 GFLOPS 的FP16 (半浮点数) ,而功耗只有5-10W。

Jetson Nano在2019年6月上市,售价99刀,国内某宝售价700-800元。


玩Jetson Nano前要准备的周边配件

买了一套Jetson Nano的开发板后,你还需要再买

  • 电源
    • 5V 2A Micro-USB电源适配器
    • 或者 5V 4A桶插孔电源适配器(更推荐)
  • Micro SD卡 (推荐128G,或者足量的64G)
  • 无线网卡
    • 推荐Intel Wireless AC8265
    • 网卡天线
  • USB键盘鼠标

Jetson Nano接口

  1. micron SD卡槽
  2. 40脚扩展头
  3. Micro-USB用于5V供电或数据传输
  4. 千兆网卡 (RJ45)
  5. 4个 USB 3.0 A
  6. HDMI 2.0输出
  7. DisplayPort 输出
  8. 5V电源输入
  9. MIPI CSI-2 连接摄像头

摄像头

对于计算机视角来说,摄像头必不可少,但由于Jetson是今年新款产品,对于以往旧芯片的摄像头就不太友好了,现在已知支持的芯片有下面几个:

品牌 型号 芯片 最大分辨率
e-con Systems e-CAM30_CUNANO AR0330 3.4 MP
Logitech C270 ? 1280×720
Logitech C920 ? 1920×1080
Leopard LI-IMX219-MIPI-FF-NANO Sony IMX219 3280×2464
Raspberry PI Camera Module V2 Sony IMX219 3280×2464
Appro AP-IMX179-MIPIx1 Sony IMX179 3280×2464
Appro AP-IMX290-MIPIx1 Sony IMX219 1920×1080
Stereolabs ZED ? 4416×1242

这里要注意的是树莓派V1.3的摄像头并不在Jetson Nano支持的列表,查找官方的论坛,Nvidia说由于V1.3的芯片OV5647已经停产,他们没有计划在为V1.3写驱动。如果你真要使用V1.3的摄像头,就要自己写驱动了。

参考资料

  1. Getting Started with Jetson Nano Guide 》
  2. Embedded Developer Zone
  3. Jetson Nano Developer Forum

 

 

ESP32上安装MicroPython的方法

步骤1: 安装esptool

运行sudo pip3 install esptool

步骤2: 连接esp32开发板,通过设备管理器查看端口

步骤3:通过esptool命令检查flash_id

C:\>esptool –port COM16 flash_id
esptool.py v2.1
Connecting…….._
Detecting chip type… ESP32
Chip is ESP32D0WDQ6 (revision 1)
Uploading stub…
Running stub…
Stub running…
Manufacturer: c8
Device: 4016
Detected flash size: 4MB
Hard resetting…

步骤4: 擦除rom的内容

C:\>esptool –port COM16 erase_flash

esptool.py v2.1
Connecting……..___
Detecting chip type… ESP32
Chip is ESP32D0WDQ6 (revision 1)
Uploading stub…
Running stub…
Stub running…
Erasing flash (this may take a while)…
Chip erase completed successfully in 5.4s
Hard resetting…

步骤5: 从micropython网站下载esp32版本的固件, 网址: https://micropython.org/download#esp32

然后写入固件,

esptool –chip esp32 –port COM16 write_flash -z 0x1000 esp32-20171122-v1.9.2-443-g236297f4.bin

步骤6: 通过Putty访问端口,注意端口的波特率要检查设备管理器,通常是115200.

 

反入侵经历-VPS突然发大量包到一个香港IP

前几天发现我的一个网站流量用尽,然后被管理员停了。还以为网站变得如此受欢迎,应该多投放广告才对。仔细分析一下流量历史发现不对劲。每天访问量最高才800多次,但向外发的包每秒平均就300多k,一天就耗掉几G的流量,估计是受到攻击了。搞了半天才发现原来被人入侵植入木马了,木马通过一个10位随机字母的程序和伪装的smtpd进行大量对外发包,而且消耗了20-30%CPU资源。把程序kill了,10来秒后又产生一个新的程序(真可恶)。经过1个多小时研究终于把木马铲除,过程分享给大家。

1.找出木马攻击的IP,用iptables封了IP以免流量再次耗尽。

开两个term用watch “netstat -apn” 和top观察有哪些IP连接变化,找到每次kill了新木马程序后IP消失(59.188.242.190)。

于是通过iptables封了那IP的连接

iptables -t filter -A INPUT -s 59.188.242.190 -p udp -j DROP
iptables -t filter -A INPUT -s 59.188.242.190 -p tcp -j DROP
iptables -t filter -A OUTPUT -d 59.188.242.190 -p udp -j DROP
iptables -t filter -A OUTPUT -d 59.188.242.190 -p tcp -j DROP
service iptables save
service iptables restart

2.找出木马在哪里,思路是用find来找出从流量不正常以来所有可执行文件进行分析,从VPS的统计中发现大概在7天前出现流量异常。

# find / -mtime -7 -type f -perm /u=x,g=x,o=x
find: /proc/5041/task/5041/fd/4: No such file or directory
find: /proc/5041/task/5041/fdinfo/4: No such file or directory
find: /proc/5041/fd/4: No such file or directory
find: /proc/5041/fdinfo/4: No such file or directory
/usr/sbin/lsof
/usr/sbin/ss
/usr/bin/zmdtepgfcd
/usr/bin/dosguvmjeh
/var/run/mount.pid
/bin/netstat
/bin/ps
/etc/rc.d/init.d/dosguvmjeh
/etc/rc.d/init.d/jbrtpbxmct
/etc/.ssh
/etc/cron.hourly/cron.sh
/lib/libgcc.so

以上红色标出的部分就是7天内修改过的可疑可执行文件,居然把系统查网络的流量的命令都感染了!马上手动把可疑文件变成不可执行,然后重启一下服务器,在top中看看木马还能不能继续出现。

果然,重启以后木马消失了。

3.删除受感染的文件,然后恢复哪些观察网络状态的命令。先从http://www.rpmfind.net/查找/bin/netstat在那个包里的,然后用yum reinstall一次。

yum reinstall lsof
#Recover ss
yum reinstall iproute
#Recover netstat
yum reinstall net-tools
#Recover ps
yum reinstall procps

如何修改WordPress上传文件大小限制

1.如何加大WP的file size上传大小限制?

由于文件上传限制通常由PHP本身的配置决定,WP只是读取PHP的配置并限制文件大小,所以要想办法修改PHP的配置。另一方面,Web server 对post内容也有限制。例如nginx对客户端请求正文的最大长度的默认值是1M,因此也需要修改。

PHP配置的修改

方法1:修改functions.php, 添加以下几行到文件中

@ini_set( ‘upload_max_size’ , ’64M’ );
@ini_set( ‘post_max_size’, ’64M’);
@ini_set( ‘max_execution_time’, ‘300’ );

方法2:修改PHP.INI,找出以下几个选项并修改

upload_max_filesize = 64M
post_max_size = 64M
max_execution_time = 300

方法3:修改htaccess文件

php_value upload_max_filesize 1024M
php_value post_max_size 1024M
php_value max_execution_time 1000
php_value max_input_time 1000

nginx的修改

在nginx.conf中,在http block中加入以下配置。

client_max_body_size 64M;