Caffe入門:LeNet模型介紹與網路訓練測試例子
學習卷積神經網路,首先需要理解卷積的概念,二維離散卷積的概念,以及卷積核在影象中進行卷積操作得出結果圖的實際直觀含義。
卷積的實際計算方式:二維卷積更正式的名字是塊迴圈矩陣(double block circulant matrix),矩陣論,Toeplitz矩陣
caffe中,預設的矩陣計算實現都是基於矩陣乘法的。
就是把卷積核在影象中的滑動通過矩陣每一行元素位置的移動來實現的。
深度神經網路在視覺中的應用主要是以層(二維矩陣的方式進行計算的)
要理解feature-map中的一個畫素就是一個神經元,普通的一個神經元的結構,權重weight與偏置bias,
卷積核的引數就是連線神經元上權重的引數,而偏執是另外的。
每個卷積核心對應一個輸入影象和卷積之後得到的特徵圖,這種關係被稱為權值共享(即一個特徵圖對應(共享)了一個卷積核與一個偏置引數);要“學習”的就是卷積核與偏置這些引數。
神經網路的訓練:BP演算法,後向傳播演算法,根植於一定的數學優化基礎知識,(有監督學習:減小模型預測值與實際值直接誤差的問題:優化問題),只需理解一般的優化問題,凸優化就是要求求解的函式的區域性最小就是全域性最小(凸函式),凸優化是一般優化問題的一個子集,機器學習與深度學習中設計的優化不用去深入凸優化問題。
現階段只要學習和了解基於梯度優化方法即可。
目錄
目錄
Caffe環境minist資料集手寫數字識別
1.1LeNet-5 卷集神經網路如下圖:
LeNet-5包含了卷積層,Pooling層,全連線層,這些層元素構成了現代CNN的基本元件,學習和研究LeNet是研究更復雜網路模型的基礎!
下圖是使用Caffe的draw_net.py指令碼,輸入LeNet-5的網路描述檔案lenet_train_test.prototxt 畫出了的網路結構圖:
Left to right:
Button to up
進入Caffe主目錄,在examples/mnist/目錄下找到LeNet的Caffe實現版本
1.2步驟:
- 資料下載
- 將原始資料生成LMDB格式的檔案
- 網路配置 .prototxt檔案
- 網路訓練
- 網路測試
1.資料下載
在caffe主目錄下執行指令碼:./data/mnist/get_mnist.sh 該指令碼檔案內容如下:
# This scripts downloads the mnist data and unzips it.
#!/usr/bin/env sh
# This scripts downloads the mnist data and unzips it.
DIR="$( cd "$(dirname "$0")" ; pwd -P )"
cd "$DIR"
echo "Downloading..."
for fname in train-images-idx3-ubyte train-labels-idx1-ubyte t10k-images-idx3-ubyte t10k-labels-idx1-ubyte
do
if [ ! -e $fname ]; then
wget --no-check-certificate http://yann.lecun.com/exdb/mnist/${fname}.gz
gunzip ${fname}.gz
fi
done
在資料夾/data/mnist/下得到: 1、train-images-idx3-ubyte 2、train-labels-idx1-ubyte 3、t10k-images-idx3-ubyte 4、t10k-labels-idx1-ubyte 4個檔案
2.回到caffe主目錄
執行./examples/mnist/create_minist.sh 指令碼檔案 將2步驟得到的資料集和標籤轉化成lmdb檔案
執行該命令可以在終端輸入:回車執行即可,也可以使用sudo sh ./examples/mnist/create_mnist.sh
sh ./examples/mnist/create_mnist.sh
在資料夾/examples/mnist下生成 mnist-train-lmdb 和mnist-test-lmdb 兩個檔案
注意:1.執行指令碼命令時若使用了sudo 則root許可權,以後使用這些檔案時也需要root許可權
3.LeNet的網路結構定義在 examples/mnist/lenet_train_test.prototxt檔案裡:
網路訓練時候的梯度下降求解模型定義在examples/mnist/solver.prototxt裡面
lenet_train_test.prototxt檔案內容如下:
name: "LeNet"
layer {
name: "mnist"
type: "Data"
top: "data"
top: "label"
include {
phase: TRAIN
}
transform_param {
scale: 0.00390625
}
data_param {
source: "examples/mnist/mnist_train_lmdb"
batch_size: 64
backend: LMDB
}
}
layer {
name: "mnist"
type: "Data"
top: "data"
top: "label"
include {
phase: TEST
}
transform_param {
scale: 0.00390625
}
data_param {
source: "examples/mnist/mnist_test_lmdb"
batch_size: 100
backend: LMDB
}
}
layer {
name: "conv1"
type: "Convolution"
bottom: "data"
top: "conv1"
param {
lr_mult: 1
}
param {
lr_mult: 2
}
convolution_param {
num_output: 20
kernel_size: 5
stride: 1
weight_filler {
type: "xavier"
}
bias_filler {
type: "constant"
}
}
}
layer {
name: "pool1"
type: "Pooling"
bottom: "conv1"
top: "pool1"
pooling_param {
pool: MAX
kernel_size: 2
stride: 2
}
}
layer {
name: "conv2"
type: "Convolution"
bottom: "pool1"
top: "conv2"
param {
lr_mult: 1
}
param {
lr_mult: 2
}
convolution_param {
num_output: 50
kernel_size: 5
stride: 1
weight_filler {
type: "xavier"
}
bias_filler {
type: "constant"
}
}
}
layer {
name: "pool2"
type: "Pooling"
bottom: "conv2"
top: "pool2"
pooling_param {
pool: MAX
kernel_size: 2
stride: 2
}
}
layer {
name: "ip1"
type: "InnerProduct"
bottom: "pool2"
top: "ip1"
param {
lr_mult: 1
}
param {
lr_mult: 2
}
inner_product_param {
num_output: 500
weight_filler {
type: "xavier"
}
bias_filler {
type: "constant"
}
}
}
layer {
name: "relu1"
type: "ReLU"
bottom: "ip1"
top: "ip1"
}
layer {
name: "ip2"
type: "InnerProduct"
bottom: "ip1"
top: "ip2"
param {
lr_mult: 1
}
param {
lr_mult: 2
}
inner_product_param {
num_output: 10
weight_filler {
type: "xavier"
}
bias_filler {
type: "constant"
}
}
}
layer {
name: "accuracy"
type: "Accuracy"
bottom: "ip2"
bottom: "label"
top: "accuracy"
include {
phase: TEST
}
}
layer {
name: "loss"
type: "SoftmaxWithLoss"
bottom: "ip2"
bottom: "label"
top: "loss"
}
lenet_solver.prototxt 檔案如下:lenet_solver.prototxt 檔案裡面定義了網路原型檔案的路徑,迭代次數,學習率,迭代多少次顯示一結果,和使用CPU還是使用GPU。
# The train/test net protocol buffer definition
net: "examples/mnist/lenet_train_test.prototxt"
# test_iter specifies how many forward passes the test should carry out.
# In the case of MNIST, we have test batch size 100 and 100 test iterations,
# covering the full 10,000 testing images.
test_iter: 100
# Carry out testing every 500 training iterations.
test_interval: 500
# The base learning rate, momentum and the weight decay of the network.
base_lr: 0.01
momentum: 0.9
weight_decay: 0.0005
# The learning rate policy
lr_policy: "inv"
gamma: 0.0001
power: 0.75
# Display every 100 iterations
display: 100
# The maximum number of iterations
max_iter: 10000
# snapshot intermediate results
snapshot: 5000
snapshot_prefix: "examples/mnist/lenet"
# solver mode: CPU or GPU
solver_mode: GPU
4.訓練網路
在caffe主目錄下執行 sh ./examples/mnist/train_lenet.sh 指令碼檔案
train_lenet.sh 指令碼的內容如下:
#!/usr/bin/env sh
set -e
./build/tools/caffe train --solver=examples/mnist/lenet_solver.prototxt [email protected]
訓練完成後在/examples/mnist/目錄下生成:
lenet_iter_5000.caffemodel lenet_iter_5000.solverstate lenet_iter_10000.caffemodel lenet_iter_10000.solverstate
分別是迭代5000次和迭代10000次訓練生成的.caffemodel caffe模型檔案和 .solverstate 求解狀態檔案
5.網路測試
回到caffe主目錄,在終端執行: sh ./examples/mnist/test_lenet.sh 命令
test_lenet.sh指令碼內容如下:
#!/usr/bin/env sh
set -e
./build/tools/caffe test -model=examples/mnist/lenet_train_test.prototxt -weights=examples/mnist/lenet_iter_10000.caffemodel -gpu=0
此指令碼呼叫caffe主目錄下的tools目錄裡面的test命名,帶上網路的定義檔案.prototxt和訓練的caffe模型的權重引數檔案.caffemodel 和指定使用第一塊gpu進行運算。
6.mnist資料集轉換成bmp圖片資料:
mnist2bmp.py 將訓練資料集轉換成bmp影象格式
import numpy as np
import struct
import matplotlib.pyplot as plt
#import Image
from PIL import Image,ImageFont
filename='t10k-images-idx3-ubyte'
binfile=open(filename,'rb')
buf=binfile.read()
index=0
s=struct.Struct('>IIII');
#magic,numImages,numRows,numColumns=strcut.unpack_from('>IIII',buf,index)
magic,numImages,numRows,numColumns=s.unpack_from(buf,index)
index+=struct.calcsize('>IIII')
for image in range(0,numImages):
im=struct.unpack_from('>784B',buf,index) #28*28=784
index+=struct.calcsize('>784B')
im=np.array(im,dtype='uint8')
im=im.reshape(28,28)
im=Image.fromarray(im)
im.save('mnist_test/test_%s.bmp'%image,'bmp')
python若有中文註釋的話,檔案的儲存需要使用utf-8編碼
在python檔案的第一行加:
# -*- coding:utf-8 -*-
上面的mnist2bmp.py 使用的python的struct模組:
該模組可以格式化地讀寫二進位制檔案資料
'>IIII' 的意思是 :>表示是大端序,即網路位元組順序;大寫的I表示4位元組的整型數。
7.minis圖片手寫數字測試
下面的指令碼完成載入網路模型和引數檔案,輸入一幅28*28的手寫數字,並輸出識別結果:
# -*- coding:utf-8 -*-
#有中文註釋的話需要utf-8編碼
import os
import sys
import numpy as np
import matplotlib.pyplot as plt
caffe_root='/home/yang/caffe/' #設定Caffe環境的根目錄
sys.path.insert(0,caffe_root+'python') #新增系統環境變數
import caffe
MODEL_FILE='/home/yang/caffe/examples/mnist/lenet.prototxt' #Lenet網路的定義檔案
PRETRAINED='/home/yang/caffe/examples/mnist/lenet_iter_10000.caffemodel' #網路模型引數
IMAGE_FILE='/home/yang/caffe/data/mnist/mnist_test/test_0.bmp' #測試圖片路徑
input_image=caffe.io.load_image(IMAGE_FILE,color=False)
net=caffe.Classifier(MODEL_FILE,PRETRAINED)
prediction=net.predict([input_image],oversample=False)
caffe.set_mode_cpu()
print 'predicted class:',prediction[0].argmax()
輸出如下:預測結果為數字7
$ python caffeP103LeNet.py
/home/yang/.local/lib/python2.7/site-packages/skimage/io/_io.py:49: UserWarning: `as_grey` has been deprecated in favor of `as_gray`
warn('`as_grey` has been deprecated in favor of `as_gray`')
WARNING: Logging before InitGoogleLogging() is written to STDERR
I1120 19:10:51.107837 6016 net.cpp:53] Initializing net from parameters:
name: "LeNet"
state {
phase: TEST
level: 0
}
layer {
name: "data"
type: "Input"
top: "data"
input_param {
shape {
dim: 64
dim: 1
dim: 28
dim: 28
}
}
}
layer {
name: "conv1"
type: "Convolution"
bottom: "data"
top: "conv1"
param {
lr_mult: 1
}
param {
lr_mult: 2
}
convolution_param {
num_output: 20
kernel_size: 5
stride: 1
weight_filler {
type: "xavier"
}
bias_filler {
type: "constant"
}
}
}
layer {
name: "pool1"
type: "Pooling"
bottom: "conv1"
top: "pool1"
pooling_param {
pool: MAX
kernel_size: 2
stride: 2
}
}
layer {
name: "conv2"
type: "Convolution"
bottom: "pool1"
top: "conv2"
param {
lr_mult: 1
}
param {
lr_mult: 2
}
convolution_param {
num_output: 50
kernel_size: 5
stride: 1
weight_filler {
type: "xavier"
}
bias_filler {
type: "constant"
}
}
}
layer {
name: "pool2"
type: "Pooling"
bottom: "conv2"
top: "pool2"
pooling_param {
pool: MAX
kernel_size: 2
stride: 2
}
}
layer {
name: "ip1"
type: "InnerProduct"
bottom: "pool2"
top: "ip1"
param {
lr_mult: 1
}
param {
lr_mult: 2
}
inner_product_param {
num_output: 500
weight_filler {
type: "xavier"
}
bias_filler {
type: "constant"
}
}
}
layer {
name: "relu1"
type: "ReLU"
bottom: "ip1"
top: "ip1"
}
layer {
name: "ip2"
type: "InnerProduct"
bottom: "ip1"
top: "ip2"
param {
lr_mult: 1
}
param {
lr_mult: 2
}
inner_product_param {
num_output: 10
weight_filler {
type: "xavier"
}
bias_filler {
type: "constant"
}
}
}
layer {
name: "prob"
type: "Softmax"
bottom: "ip2"
top: "prob"
}
I1120 19:10:51.107987 6016 layer_factory.hpp:77] Creating layer data
I1120 19:10:51.108000 6016 net.cpp:86] Creating Layer data
I1120 19:10:51.108006 6016 net.cpp:382] data -> data
I1120 19:10:51.108021 6016 net.cpp:124] Setting up data
I1120 19:10:51.108026 6016 net.cpp:131] Top shape: 64 1 28 28 (50176)
I1120 19:10:51.108033 6016 net.cpp:139] Memory required for data: 200704
I1120 19:10:51.108037 6016 layer_factory.hpp:77] Creating layer conv1
I1120 19:10:51.108047 6016 net.cpp:86] Creating Layer conv1
I1120 19:10:51.108052 6016 net.cpp:408] conv1 <- data
I1120 19:10:51.108057 6016 net.cpp:382] conv1 -> conv1
I1120 19:10:51.806463 6016 net.cpp:124] Setting up conv1
I1120 19:10:51.806486 6016 net.cpp:131] Top shape: 64 20 24 24 (737280)
I1120 19:10:51.806499 6016 net.cpp:139] Memory required for data: 3149824
I1120 19:10:51.806514 6016 layer_factory.hpp:77] Creating layer pool1
I1120 19:10:51.806524 6016 net.cpp:86] Creating Layer pool1
I1120 19:10:51.806529 6016 net.cpp:408] pool1 <- conv1
I1120 19:10:51.806535 6016 net.cpp:382] pool1 -> pool1
I1120 19:10:51.806552 6016 net.cpp:124] Setting up pool1
I1120 19:10:51.806556 6016 net.cpp:131] Top shape: 64 20 12 12 (184320)
I1120 19:10:51.806562 6016 net.cpp:139] Memory required for data: 3887104
I1120 19:10:51.806565 6016 layer_factory.hpp:77] Creating layer conv2
I1120 19:10:51.806576 6016 net.cpp:86] Creating Layer conv2
I1120 19:10:51.806581 6016 net.cpp:408] conv2 <- pool1
I1120 19:10:51.806586 6016 net.cpp:382] conv2 -> conv2
I1120 19:10:51.808470 6016 net.cpp:124] Setting up conv2
I1120 19:10:51.808481 6016 net.cpp:131] Top shape: 64 50 8 8 (204800)
I1120 19:10:51.808488 6016 net.cpp:139] Memory required for data: 4706304
I1120 19:10:51.808497 6016 layer_factory.hpp:77] Creating layer pool2
I1120 19:10:51.808506 6016 net.cpp:86] Creating Layer pool2
I1120 19:10:51.808509 6016 net.cpp:408] pool2 <- conv2
I1120 19:10:51.808516 6016 net.cpp:382] pool2 -> pool2
I1120 19:10:51.808526 6016 net.cpp:124] Setting up pool2
I1120 19:10:51.808531 6016 net.cpp:131] Top shape: 64 50 4 4 (51200)
I1120 19:10:51.808537 6016 net.cpp:139] Memory required for data: 4911104
I1120 19:10:51.808542 6016 layer_factory.hpp:77] Creating layer ip1
I1120 19:10:51.808552 6016 net.cpp:86] Creating Layer ip1
I1120 19:10:51.808557 6016 net.cpp:408] ip1 <- pool2
I1120 19:10:51.808563 6016 net.cpp:382] ip1 -> ip1
I1120 19:10:51.811174 6016 net.cpp:124] Setting up ip1
I1120 19:10:51.811182 6016 net.cpp:131] Top shape: 64 500 (32000)
I1120 19:10:51.811187 6016 net.cpp:139] Memory required for data: 5039104
I1120 19:10:51.811197 6016 layer_factory.hpp:77] Creating layer relu1
I1120 19:10:51.811213 6016 net.cpp:86] Creating Layer relu1
I1120 19:10:51.811216 6016 net.cpp:408] relu1 <- ip1
I1120 19:10:51.811221 6016 net.cpp:369] relu1 -> ip1 (in-place)
I1120 19:10:51.825971 6016 net.cpp:124] Setting up relu1
I1120 19:10:51.825984 6016 net.cpp:131] Top shape: 64 500 (32000)
I1120 19:10:51.825992 6016 net.cpp:139] Memory required for data: 5167104
I1120 19:10:51.825999 6016 layer_factory.hpp:77] Creating layer ip2
I1120 19:10:51.826009 6016 net.cpp:86] Creating Layer ip2
I1120 19:10:51.826014 6016 net.cpp:408] ip2 <- ip1
I1120 19:10:51.826022 6016 net.cpp:382] ip2 -> ip2
I1120 19:10:51.826073 6016 net.cpp:124] Setting up ip2
I1120 19:10:51.826079 6016 net.cpp:131] Top shape: 64 10 (640)
I1120 19:10:51.826086 6016 net.cpp:139] Memory required for data: 5169664
I1120 19:10:51.826094 6016 layer_factory.hpp:77] Creating layer prob
I1120 19:10:51.826102 6016 net.cpp:86] Creating Layer prob
I1120 19:10:51.826107 6016 net.cpp:408] prob <- ip2
I1120 19:10:51.826114 6016 net.cpp:382] prob -> prob
I1120 19:10:51.826570 6016 net.cpp:124] Setting up prob
I1120 19:10:51.826580 6016 net.cpp:131] Top shape: 64 10 (640)
I1120 19:10:51.826586 6016 net.cpp:139] Memory required for data: 5172224
I1120 19:10:51.826592 6016 net.cpp:202] prob does not need backward computation.
I1120 19:10:51.826597 6016 net.cpp:202] ip2 does not need backward computation.
I1120 19:10:51.826603 6016 net.cpp:202] relu1 does not need backward computation.
I1120 19:10:51.826608 6016 net.cpp:202] ip1 does not need backward computation.
I1120 19:10:51.826613 6016 net.cpp:202] pool2 does not need backward computation.
I1120 19:10:51.826619 6016 net.cpp:202] conv2 does not need backward computation.
I1120 19:10:51.826625 6016 net.cpp:202] pool1 does not need backward computation.
I1120 19:10:51.826630 6016 net.cpp:202] conv1 does not need backward computation.
I1120 19:10:51.826637 6016 net.cpp:202] data does not need backward computation.
I1120 19:10:51.826642 6016 net.cpp:244] This network produces output prob
I1120 19:10:51.826650 6016 net.cpp:257] Network initialization done.
I1120 19:10:51.843571 6016 net.cpp:746] Ignoring source layer mnist
I1120 19:10:51.844007 6016 net.cpp:746] Ignoring source layer loss
/home/yang/.local/lib/python2.7/site-packages/skimage/transform/_warps.py:110: UserWarning: Anti-aliasing will be enabled by default in skimage 0.15 to avoid aliasing artifacts when down-sampling images.
warn("Anti-aliasing will be enabled by default in skimage 0.15 to "
predicted class: 7
2.Caffe網路模型要素及構成
Caffe的模型需要兩個重要的引數檔案:1.網路模型定義檔案*.prototxt;2.網路引數檔案*.solver.prototxt;
網路引數檔案可以認為是經過訓練演算法求解得到網路引數後得到的,所以命名是*.solver.prototxt;
Caffe的網路模型定義檔案定義了網路每一層的行為(行為描述)
2.1LeNet模型
看右路分支:data->conv1->pool1->conv2->pool2->ip1->(relu1)->ip2->loss(softMaxWithLoss)
依次瞭解:資料層(訓練資料層和測試資料層)、卷積層、池化層、內積(全連線)層、ReLU層、Loss層、
1.資料層
網路模型的輸入層為資料層,即網路模型的資料輸入定義,一般包括訓練資料和測試資料層兩種型別。
source欄位指明資料庫檔案的路徑;
bachsize:指明批處理的大小
scale:取值在[0,1]區間
layer {
name: "mnist"
type: "Data"
top: "data"
top: "label"
include {
phase: TRAIN
}
transform_param {
scale: 0.00390625
}
data_param {
source: "examples/mnist/mnist_train_lmdb"
batch_size: 64
backend: LMDB
}
}
layer {
name: "mnist"
type: "Data"
top: "data"
top: "label"
include {
phase: TEST
}
transform_param {
scale: 0.00390625
}
data_param {
source: "examples/mnist/mnist_test_lmdb"
batch_size: 100
backend: LMDB
}
}
2.卷積層
blobs_lr:1,blobs_lr:2 分別表示weight和bias更新時的學習率,這裡的權值學習率為solver.prototxt中定義的學習率。
bias學習率為權重學習了的兩倍,這樣會得到較好的收斂速度。
num_output表示濾波器的個數;kernel_size是濾波核的大小,stride是濾波器的滑動步長,
weight_filter表示濾波器的型別;
xavier(發音[‘zeɪvɪr]):是從[-scale,scale]中進行均勻取樣,對卷積層或全連線層中的引數進行初始化的方法。
xavier:caffe中具體是怎樣實現的,程式碼位於include/caffe/filler.hpp檔案中
#代表註釋
layer {
name: "conv1"
type: "Convolution"
bottom: "data"
top: "conv1"
param {
lr_mult: 1 #權重weight的學習率
}
param {
lr_mult: 2 #偏置bias的學習率,一般為weight學習率的兩倍
}
convolution_param {
num_output: 20 #卷積核(濾波器)的個數
kernel_size: 5 #卷積核的大小5*5
stride: 1 #卷積核的滑動步長1
weight_filler {
type: "xavier" #濾波器的型別
}
bias_filler {
type: "constant" #偏置的初始化方式
}
}
}
3.Pooling層
layer {
name: "pool1"
type: "Pooling"
bottom: "conv1"
top: "pool1"
pooling_param {
pool: MAX
kernel_size: 2
stride: 2
}
}
4.內積(全連線)層
layer {
name: "ip1"
type: "InnerProduct"
bottom: "pool2"
top: "ip1"
param {
lr_mult: 1
}
param {
lr_mult: 2
}
inner_product_param {
num_output: 500
weight_filler {
type: "xavier"
}
bias_filler {
type: "constant"
}
}
}
5.ReLU(矯正線性單元)Rectifier Line Uint
非線性變化層:max(0,x)
一般與卷積層成對出現。
layer {
name: "relu1"
type: "ReLU"
bottom: "ip1"
top: "ip1"
}
6.Softmax層
layer {
name: "loss"
type: "SoftmaxWithLoss"
bottom: "ip2"
bottom: "label"
top: "loss"
}
caffe LeNet 計算機視覺-深度學習入門
2.2 引數配置檔案(訓練後得到的網路引數檔案)
*.slover.ptototxt檔案
Caffe的引數配置檔案*.slover.prototxt定義了網路模型訓練過程中需要設定的引數,比如,學習率、權重衰減係數、迭代次數,使用GPU還是CPU進行計算。
參考文獻:
[1]深度學習 Caffe之經典模型詳解與實戰P88
相關推薦
Caffe入門:LeNet模型介紹與網路訓練測試例子
學習卷積神經網路,首先需要理解卷積的概念,二維離散卷積的概念,以及卷積核在影象中進行卷積操作得出結果圖的實際直觀含義。 卷積的實際計算方式:二維卷積更正式的名字是塊迴圈矩陣(double block circulant matrix),矩陣論,Toeplitz矩陣 caf
Caffe配置:引數的介紹入門
利用Caffe進行深度神經網路訓練第一步需要搞懂幾個重要檔案: solver.prototxttrain_val.prototxttrain.sh 接下來我們按順序一個個說明。 solver.prototxt solver這個檔案主要存放模型訓練所用到的一些超引數:
GitHub入門:如何上傳與下載工程?
由於經常要在家寫程式碼,所以需要有個能夠方便訪問程式碼管理工具。最近嘗試了一下GitHub。經過了一翻糾結之後,基本上掌握了他的使用方式。 要使用GitHub需要首先在其網站上進行註冊。其官方網站是https://github.com/。註冊的流程在這裡就不多少了,大家按照它的提示,一步
從零開始山寨Caffe·貳:主存模型
本文轉自:https://www.cnblogs.com/neopenx/p/5190282.html 從硬體說起 物理之觴 大部分Caffe原始碼解讀都喜歡跳過這部分,我不知道他們是什麼心態,因為這恰恰是最重要的一部分。 記憶體的管理不擅,不僅會導致程式的立即崩潰,還會導致記憶體的
【資料庫系統概念】第二章:關係模型介紹
關係資料庫的結構 關係(relation) 關係資料庫由表(table)的集合構成。 在關係模型的術語中,關係就用來指代表。 元組(tuple) 指代表中的一行,表示一組值的序列(或列
《資料庫系統概念》第二章:關係模型介紹
關係資料庫的結構 關係(relation) 關係資料庫由表(table)的集合構成。 在關係模型的術語中,關係就用來指代表。 元組(tuple) 指代表中的一行,表示一組值的序列(或列表)。 n個
046:ORM模型介紹
ORM模型介紹: 隨著專案越來越大,採用寫原生SQL的方式在程式碼中會出現大量的SQL語句,那麼問題就出現了: 1、SQL語句重複利用率不高,越複雜的SQL語句條件越多,程式碼越長。會出現很多相近的SQL語句;2、很多SQL語句是在業務邏輯中拼出來的,如果有資料庫需要更改,就要去修改這些邏輯,這會很容
kotlin學習筆記:object關鍵字介紹與java中的靜態變數與靜態方法的實現以及@JvmField和@JvmStatic的使用
在java中,靜態變數和靜態方法是我們經常需要用到的東西,但是我們在kotlin中,並不能找到static關鍵字。其實目前在kotlin中,也的確是static概念的,那麼我們該如何在kotlin中實現靜態變數和靜態方法呢?這時就要用到kotlin中的obje
深入理解JVM虛擬機器4:Java class介紹與解析實踐
深入理解JVM虛擬機器4:Java class介紹與解析實踐 轉自https://juejin.im/post/589834a20ce4630056097a56 前言 身為一個java程式設計師,怎麼能不瞭解JVM呢,倘若想學習JVM,那就又必須要了解Class檔案,Class之
Pytorch入門:資料的載入與處理
0. 寫在前面 在深度學習的問題中處理資料都會佔據比較大的時間,只有把資料處理好了才有可能對模型進行訓練、測試等後續工作。 PyTorch提供了很多用於讓資料載入變得更加方便的工具,接下來我們就來學習一下怎麼樣處理那些PyTorch沒有提供直接介面的資料。 在學
Linux入門:Linux歷史介紹
通過本篇文章,讀者可以瞭解Linux和Unix的基本概念、歷史、發展情況; 首先,我們通過簡單的介紹Unix和Linux,讀者可以對其進行比較不同之處,瞭解Linux的出現為何非常好,Linux的相關背景; 前言(1):作業系統介紹 核心負責控制硬體資源分配,而如果只有
Android 基礎:Fragment的介紹與應用,QQ底欄,側滑選單
Fragment介紹 Android是在Android 3.0 (API level 11)開始引入Fragment的。可以把Fragment當成Activity的一個介面的一個組成部分,甚至Activity的介面可以完全有不同的Fragment組成,而且Fragmen
python資料分析與挖掘實戰筆記二:第99頁神經網路訓練出現的錯誤'Some keys in session_kwargs are not supported at this time: %s'
在使用神經網路模型預測銷量高低時,系統指出模型訓練時出現錯誤: ValueError Traceback (most recent call last) <ipython-input-20-e46e29b76a5e> in <module&g
Android入門:廣播發送者與廣播接收者
一、廣播發送者&廣播接收者介紹 1.廣播接收者 廣播接收者簡單地說就是接收廣播意圖的Java類,此Java類繼承BroadcastReceiver類,重寫: public void onReceive(Context context,Intent in
JMeter入門:01JMeter總體介紹及元件介紹
一、JMeter概述 JMeter就是一個測試工具,相比於LoadRunner等測試工具,此工具免費,且比較好用,但是前提當然是安裝Java環境; JMeter可以做 (1)壓力測試及效能測試; (2)資料庫測試; (3)Java程式的測試; (4)HTTP及FTP
新手入門:瞭解WWW服務與HTTP協議(一)
歷史上,先後問世了多個具有重大社會影響的電子通訊技術。第一個這樣的技術是19世紀70年代發明的電話。電話使得不在同一物理位置的兩人得以實時 地口頭交流。它對社會有重大的影響——有好的也有壞的。下一個電子通訊技術是20世紀20年代及30年代問世的廣播收音機/電視機。廣播收音
Scratch入門:軟體介面介紹
當我們開啟Scratch軟體後,首先呈現的介面就是我們日後搭建程式的主介面,程式就是這裡來製作的。 整個使用者介面大致包含三個部份:左上方的舞臺、左下方的角色列表、右邊與腳 本相關的區域(包括積木區和指令碼區)。標籤頁中除了指令碼和標籤頁,還包括造型標籤頁和聲
Spring Cloud認知學習(一):Spring Cloud介紹與Eureka使用
[toc] -------- 這是一個Spring Cloud系列文章,它並不會講解所有的知識點,它只是基於微服務的場景來**逐步介紹**常見元件的作用和意義,以及場景元件的整合。對於每個元件的知識並不會講解太多,只講常見的,目的是儘可能快速的對Spring Cloud的常用元件有一個基礎的認知,有
MySQL全面瓦解3:資料型別介紹與分析
概述 MySQL支援很多資料型別,以便我們能在複雜的業務場景中支援各種各樣的資料格式,儲存適當的資料內容。我們在設計資料庫時,正確的使用資料庫型別對整個資料庫的整潔和高效,會有很大的幫助。 目前常用的資料型別大致上可以分為4大類:整數型別、浮點數型別、字串(字元)型別、日期/時間型別。詳細如下 4大類
Kafka筆記整理(三):消費形式驗證與性能測試
大數據 Kafka 性能測試 [TOC] Kafka筆記整理(三):消費形式驗證與性能測試 Kafka消費形式驗證 前面的《Kafka筆記整理(一)》中有提到消費者的消費形式,說明如下: 1、每個consumer屬於一個consumer group,可以指定組id。group.id 2、消費形