回归的定义

Regression就是指找到一个函数$function$,通过输入特征x,输出一个数值$Scalar$

看了李宏毅老师的机器学习课程视频,其中的Regression demo部分,关于预测宝可梦的CP值的应用代码,在jupyter notebook中实现。
现在假设有10个x_data和y_data,x和y之间的关系是y_data=b+w*x_data。b,w都是参数,是需要学习出来的。现在我们来练习用梯度下降找到b和w。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
%matplotlib inline
plt.rcParams['font.sans-serif'] = ['Simhei'] # 显示中文
mpl.rcParams['axes.unicode_minus'] = False # 解决保存图像是负号'-'显示为方块的问题

x_data= [ 338., 333., 328., 207., 226., 25., 179., 60., 208., 606.]
y_data= [ 640., 633., 619., 393., 428., 27., 193., 66., 226., 1591.]
# ydata =b + w * xdata

x = np.arange(-200, -100, 1) #bias
y = np.arange(-5,5,0.1) #weight
Z = np.zeros((len(x), len(y)))
X, Y = np.meshgrid(x, y)
for i in range(len(x)):
for j in range(len(y)):
b = x[i]
w = y[j]
Z[j][i] = 0
for n in range(len(x_data)):
Z[j][i] = Z[j][i] + (y_data[n] - b - w*x_data[n]) **2
Z[j][i] = Z[j][i] /len(x_data)

# ydata = b + w * xdata
b = -120 # initial b
w = -4 #intial w
lr =0.0000001
iteration = 100000
# Store initial values for plotting.
b_history = [b]
w_history = [w]

#lr_b = 0 #客制化b的learning rate 的初始值
#lr_w = 0 #客制化w的learning rate 的初始值

# Iterations
for i in range(iteration):

b_grad = 0.0
w_grad = 0.0
for n in range(len(x_data)):
b_grad = b_grad - 2.0*(y_data[n] - b - w*x_data[n]) *1.0
w_grad = w_grad - 2.0*(y_data[n] - b - w*x_data[n])*x_data[n]

# lr_b = lr_b + b_grad ** 2 #客制化b的learning rate
# lr_w = lr_w + w_grad ** 2 #客制化w的learning rate

# Update parameters.
b = b - lr * b_grad
w = w - lr * w_grad

# Store parameters for plotting
b_history.append(b)
w_history.append(w)

# plot the figure
plt.contourf(x, y, Z, 50, alpha = 0.5, cmap=plt.get_cmap('jet'))
plt.plot([-188.4], [2.67], 'x', ms = 12, markeredgewidth = 3, color='orange')
plt.plot(b_history, w_history, 'o-', ms=3, lw=1.5, color='black')
plt.xlim(-200, -100)
plt.ylim(-5,5)
plt.xlabel(r'$b$', fontsize=16)
plt.ylabel(r'$w$', fontsize=16)
plt.title("线性回归")
plt.show()


输出结果图:

横坐标是b,纵坐标是w,标记×位最优解,显然,在图中我们并没有运行得到最优解,最优解十分的遥远。那么我们就调大learning rate,lr = 0.000001(调大10倍),得到结果如下图。

我们再调大learning rate,lr = 0.00001(调大10倍),得到结果如下图。

结果发现learning rate太大了,结果很不好。
所以我们给b和w特制化两种learning rate
修改后代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
%matplotlib inline
plt.rcParams['font.sans-serif'] = ['Simhei'] # 显示中文
mpl.rcParams['axes.unicode_minus'] = False # 解决保存图像是负号'-'显示为方块的问题

x_data= [ 338., 333., 328., 207., 226., 25., 179., 60., 208., 606.]
y_data= [ 640., 633., 619., 393., 428., 27., 193., 66., 226., 1591.]
# ydata =b + w * xdata

x = np.arange(-200, -100, 1) #bias
y = np.arange(-5,5,0.1) #weight
Z = np.zeros((len(x), len(y)))
X, Y = np.meshgrid(x, y)
for i in range(len(x)):
for j in range(len(y)):
b = x[i]
w = y[j]
Z[j][i] = 0
for n in range(len(x_data)):
Z[j][i] = Z[j][i] + (y_data[n] - b - w*x_data[n]) **2
Z[j][i] = Z[j][i] /len(x_data)

# ydata = b + w * xdata
b = -120 # initial b
w = -4 #intial w
lr =1 #learning rate设为1
iteration = 100000
# Store initial values for plotting.
b_history = [b]
w_history = [w]

lr_b = 0 #客制化b的learning rate 的初始值
lr_w = 0 #客制化w的learning rate 的初始值

# Iterations
for i in range(iteration):

b_grad = 0.0
w_grad = 0.0
for n in range(len(x_data)):
b_grad = b_grad - 2.0*(y_data[n] - b - w*x_data[n]) *1.0
w_grad = w_grad - 2.0*(y_data[n] - b - w*x_data[n])*x_data[n]

lr_b = lr_b + b_grad ** 2 #客制化b的learning rate
lr_w = lr_w + w_grad ** 2 #客制化w的learning rate

# Update parameters.
b = b - lr/np.sqrt(lr_b ) * b_grad
w = w - lr/np.sqrt(lr_w ) * w_grad

# Store parameters for plotting
b_history.append(b)
w_history.append(w)

# plot the figure
plt.contourf(x, y, Z, 50, alpha = 0.5, cmap=plt.get_cmap('jet'))
plt.plot([-188.4], [2.67], 'x', ms = 12, markeredgewidth = 3, color='orange')
plt.plot(b_history, w_history, 'o-', ms=3, lw=1.5, color='black')
plt.xlim(-200, -100)
plt.ylim(-5,5)
plt.xlabel(r'$b$', fontsize=16)
plt.ylabel(r'$w$', fontsize=16)
plt.title("线性回归")
plt.show()

这样有了新的特制化两种learning rate就可以在10w次迭代之内到达最优点了。

pangu开发板介绍

pangu开发板主芯片基于ST公司STM32MP1系列微处理器(ARM dual Cortex-A7 650Mhz + Cortex-M4)

开发软件安装,STM32CubeMX

STM32CubeMX 是 ST 意法半导体近几年来大力推荐的 STM32 芯片图形化配置工具, 允许用户使用图形化向导生成 C 初始化代码,可以大大减轻开发工作,时间和费用。stm32mp1中使用协处理器M4需要安装stm32cubemx:
stm32cubemx运行环境搭建,包含两个部分,首先是安装java运行环境(版本必须为v1.7以上),然后是安装stm32cubemx开发软件。
简单使用:
新建工程第一步,选择mcu型号

由于pangu开发板选用的是stm32mp157AAA3芯片,故选择stm32mp157AAAX

接下来配置时钟源,如果选择使用外部高速时钟(HSE),则需要在System Core中配置RCC;

如果使用默认内部时钟(HSI),这一步可以略过;这里使用外部时钟,HSE,LSE
pangu开发板上的外部时钟

下拉框中选择crystal/Ceramic Resonator晶体/陶瓷晶振

设置开发板上D17灯对应的PH6引脚为输出

生成工程设置

然后点击Generate code就可生成MDK工程代码。
时钟树配置,配置主要是外部晶振大小,分频系数,倍频系统以及选择器。

最后用MDK打开生成的MDK-ARM工程文件,build编译。0error。

之前使用的STM32F407开发板用的是标准外设库(STD库), HAL库是硬件抽象层,更加标准化了。所有的函数名和函数体进行了重新定义,重新编写。更加通用。方便移植。近两年新出的STM32芯片,ST只提供HAL库,可用STM32Cube程序生成开发工具+HAL库
stm32cube目前几乎支持STM32全系列,我们需要到ST官网下载对应的STM32Cube包

包中大致有(1)Drivers文件夹,Drivers 文件夹包含BSP, CMSIS 和 STM32MP1xx_HAL_Driver 三个子文件夹。BSP是板级支持包,提供直接与硬件打交道的API。
CMSIS 文件夹是符合 CMSIS 标准的软件抽象层组件相关文件。主要包括 DSP库(DSP_LIB 文件夹), Cortex-M 内核及其设备文件(Include 文件夹), 微控制器专用头文件/启动代码/专用系统文件等(Device 文件夹)。
STM32MP1xx_HAL_Driver文件夹中包含所有的 STM32MP1xx系列 HAL 库头文件和源文件,也就是所有底层硬件抽象层 API 声明和定义。 它的作用是屏蔽了复杂的硬件寄存器操作,统一了外设的接口函数。 该文件夹包含 Src 和 Inc 两个子文件夹,其中 Src 子文件夹存放的是.c 源文件, Inc 子文件夹存放的是与之对应的.h 头文件。每个.c 源文件对应一个.h 头文件。
Middlewares文件夹下有Third_Party文件夹(是第三方中间件)里面有FreeRTOS实时系统支持包和OpenAMP(?)
Projects文件夹存放的是一些可以直接编译的实例工程,每个文件夹对应一个ST官方的Demo板,暂时只有SW4STM32的工程,没有MDK的。

一般来说,stm32mp1处理器可以在M4上做电机控制,A7上做人机交互界面。

应用开发环境搭建

linux开发需要在ubuntu下进行,主要是交叉编译器的安装。

linux进行C语言开发用的是GCC编译器进行代码编译,但ubuntu自带的GCC编译器是针对X86架构的。我们现在要编译的是ARM架构的代码,需要一个在X86架构的PC机上运行,可以编译ARM架构代码的GCC编译器,这个编译器就叫做交叉编译器。(就是在一个架构上编译另外一个架构的代码)

pangu开发板的开发环境基于Ubuntu16.04 64bit,在虚拟机上安装ubuntu16.04操作系统

  • PanGu开发板的应用开发,需要先安装应用开发工具包(SDK)。PanGu开发板提供了两种SDK工具包:i2som-image-qt-openstlinux-eglfs-pangu-x86_64-toolchain-2.6-snapshot.sh和i2som-image-weston-openstlinux-weston-pangu-x86_64-toolchain-2.6-snapshot.sh。

由于板载的flash预装的是weston系统,在此我选择在ubuntu系统中安装weston系统镜像的应用开发工具链。
下面开始安装i2som-image-weston-openstlinux-weston-pangu-x86_64-toolchain-2.6-snapshot.sh工具包

  • 首先运行chmod a+x命令,给所有人加上可执行权限,用ls –lh命令查询文件的大小、权限等详细信息,权限都为rwx(读取、写入、执行)

  • 接着在路径下运行安装命令:./i2som-image-weston-openstlinux-weston-pangu-x86_64-toolchain-2.6-snapshot.sh

  • 安装路径输入 /opt/st/pangu-i2som-image-weston/2.6-snapshot

  • 接着会让你输入管理员密码,之后就等待安装了。
    当出现SDK has been successfully时证明安装完成了。

  • 然后运行如下命令:
    ==. /opt/st/pangu-i2som-image-weston/2.6-snapshot/environment-setup-cortexa7t2hf-neon-vfpv4-openstlinux_weston-linux-gnueabi==

  • 通过$CC –version验证开发工具是否正确安装,如图显示了版本信息表示工具链安装完成。

编写测试文件test.c内容如下

编译test应用

然后将输出的 复制到pangu开发板后直接运行

通过MobaXtern配置ssh登录pangu开发板,可通过sftp服务进行文件的复制拷贝。
  上图是pangu开发板的home目录
现在将编译输出的test从虚拟机的ubuntu系统复制到home目录下

可以看到此时多了个test文件。

直接运行发现permission denied
通过chmod a+x命令修改下权限,紧接着再输入./test
输出是hello,I am wangrongyao!

pangu开发板的Micro usb接口可以作为从设备,默认是作为usb以太网设备,可以实现将开发板的usb otg接口作为从设备模式,模拟成为一个网口,通过PC的usb接口连接到开发板。使用Micro USB线连接开发板J5和PC USB Host接口。PanGu开发板上usb0为网络设备,默认IP地址为192.168.7.2

PC通过usb连接开发板后,PC上会出现一个usb虚拟的网络设备,自行手动配置ip地址为192.168.7.10,之后就可以通过ssh登录pangu开发板了。

一级标题


1. 斜体和粗体

使用 * 和 ** 表示斜体和粗体。

示例:

这是 斜体,这是 粗体

阅读全文 »