图像插值算法及其优化

研究背景及其意义

图像放大旋转是数字图像处理中最基础的几何变换操作,其核心在于如何通过插值算法重建原始图像中不存在的像素信息。当对图像进行放大操作时,输出图像的像素网格会超出原始图像的采样范围,需要通过插值来填补这些新增像素点的颜色值;而在旋转操作中,即使保持图像尺寸不变,原始像素的整数坐标经过旋转变换后也会落在新图像的非整数位置,同样需要通过插值来重新确定每个输出像素的颜色值。

图像插值是利用原图像中的颜色值通过一定的方法计算出待插入像素点的颜色值的过程。对图像进行插值一般有两个步骤:首先定义一个图像插值公式,然后利用该插值公式计算待插入点的颜色值。常见的图像插值算法有双线性法、最近邻法、非均匀法、双三次卷积插值法、双立方法、Lagrange法、 样条插值法、 克里金(Krijing) 插值法等。这些插值方法通常定义一个插值数据点的隐式函数,再提取该函数的等值面作为图像插值方法,常用的插值核包括线性插值核、样条插值核等。

  • 最近邻插值作为最简单的算法,直接将距离待插值点最近的已知像素值作为结果,虽然计算效率极高(时间复杂度O(1)),但会产生明显的块状伪影(“马赛克”)和锯齿形边缘;
  • 双线性插值通过考虑2×2邻域内四个像素的加权平均,在计算成本(O(n))和视觉效果之间取得平衡,但仍会导致高频信息丢失和边缘模糊;
  • 更高阶的双三次插值(使用4×4邻域)和样条插值虽然能提供更平滑的结果,但计算复杂度显著增加(O(n²)),且可能引入不必要的振铃效应。

现有算法的根本局限在于采用统一的插值核函数处理整幅图像,忽视了图像不同区域的特征差异。例如,在平坦区域使用复杂插值会造成计算资源浪费,而在纹理丰富区域使用简单插值又会导致细节损失。基于此,我们希望通过改良的四平面插值算法对图像的放大与旋转效果进行优化,根据图像局部特征自适应地选择不同的插值策略,以规避用同一个插值公式对所有像素进行插值存在的不足。

常用图像插值算法

课本在6.5节中提到,在插值节点数量较多时,为避免Runge振荡现象的发生,并不提倡用高次多项式进行插值,而宁可用低次多项式作分段插值。在图像处理这一特定的应用场景中,需要处理的图像尺寸规模往往较大,且同一行(列)的所有像素颜色值显然并不具有可以用一个多项式函数显式表达的规律,但相邻的像素点颜色值之间又存在一定的关联性,因此分段插值仅考虑局部特征的特性在这里能够良好地契合所需性能。根据对于待插入像素点周围已有的像素点信息的利用情况,这里列举了几种常见的图像插值算法:

  • 最近邻法:仅利用待插值像素点转换至原图像坐标后距离其最近的一个像素点的颜色值,将其直接作为待插值像素点的颜色值
  • 双线性法:利用待插值像素点转换至原图像坐标后距离其最近的四个像素点的颜色值,加权平均后作为待插值像素点的颜色值
  • 双立方法:利用待插值像素点转换至原图像坐标后距离其最近的十六个像素点的颜色值,加权平均后作为待插值像素点的颜色值

最近邻法

一维最近邻插值示意图

如上图所示,在一维最近邻插值中,坐标轴上各点 xi-1,xi,xi+1 … 两两对半等分间隔 (红色虚线划分),从而非边界的各坐标点都有一个等宽的邻域,并根据每个坐标点的值构成一个类似分段函数的函数约束,从而使各插值坐标点的值等同于所在邻域原坐标点的值。例如,插值点 x 坐落于 坐标点 xi 的邻域,那么其值 f(x) 就等于 f(xi)。

在二维的图像插值场景中,可以对上述一维最近邻插值进行推广,如下图所示:

二维最近邻插值示意图

可以看到,(x0, y0)、(x0, y1)、(x1, y0)、(x1, y1) 都是原图像上的坐标点,颜色值分别对应为 Q11、Q12、Q21、Q22。而颜色值未知的插值点 (x, y)(需转换至原图像坐标),根据最近邻插值方法的约束,其与坐标点 (x0, y0) 位置最接近 (即位于 (x0, y0) 的邻域内),故插值点 (x, y) 的颜色值 P = Q11。

总而言之,最近邻法的基本思想即:将待插入点的坐标进行四舍五入,再以该行列坐标都是整数点的颜色值(灰度值)替代待插入点(x, y)处的颜色值。事实上,这也正是机器学习中KNN(K-Nearest Neighbor)算法在K=1时的情形。

基于以上算法思想,编写python函数代码实现图像放缩与旋转过程中的最近邻法插值:

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
# 最近邻法插值实现图像放缩
def nearest_neighbor_interpolation(image, scale_factor):
h, w, channel = image.shape
new_h, new_w = int(h * scale_factor), int(w * scale_factor)
resized_image = np.zeros((new_h, new_w, int(channel)), dtype=image.dtype)

for i in range(new_h):
for j in range(new_w):
src_i = int(round((i + 1) / scale_factor, 0))
src_j = int(round((j + 1) / scale_factor, 0))
resized_image[i, j] = image[src_i - 1, src_j - 1]

return resized_image

# 最近邻法插值实现图像旋转
def nearest_neighbor_rotation(image, angle):
h, w, channel = image.shape
angle_rad = math.radians(angle)

# 计算旋转后的图像尺寸
cos_theta = abs(math.cos(angle_rad))
sin_theta = abs(math.sin(angle_rad))
new_w = int(h * sin_theta + w * cos_theta)
new_h = int(h * cos_theta + w * sin_theta)

# 旋转中心
cx, cy = w / 2, h / 2
new_cx, new_cy = new_w / 2, new_h / 2

rotated_image = np.zeros((new_h, new_w, channel), dtype=image.dtype)

for i in range(new_h):
for j in range(new_w):
# 将新图像坐标转换回原图像坐标
x = (j - new_cx) * math.cos(angle_rad) + (i - new_cy) * math.sin(angle_rad) + cx
y = -(j - new_cx) * math.sin(angle_rad) + (i - new_cy) * math.cos(angle_rad) + cy

# 最近邻插值
if 0 <= x < w and 0 <= y < h:
src_x = int(round(x))
src_y = int(round(y))
rotated_image[i, j] = image[src_y - 1, src_x - 1]

return rotated_image

双线性法

一维线性插值示意图

如上图所示,在一维的线性插值中,坐标轴上各点 xi-1,xi,xi+1 … 的值“两两直接相连”为线段,从而构成了一条连续的约束函数。而插值坐标点例如 x,根据约束函数其值应为 f(x)。因为每两个坐标点之间的约束函数曲线是一次线性的线段,对插值结果而言是“线性” 的,所以该方法称为线性插值。基于线性函数的特性,可以便捷地求取原图像上的两个像素点间任一待插值点的颜色值:

一维线性插值计算示意图

可以看到,图中 x0 和 x1 都是原有的坐标点,颜色值分别对应为 y0 和 y1,此时根据线性插值法约束,在 (x0, y0) 和 (x1, y1) 构成的一次函数上,颜色值未知的插值点 x的颜色值 y 即为:
$$
y=y_0+(x-x_0)\frac{y_1-y_0}{x_1-x_0}=y_0+\frac{(x-x_0)y_1-(x-x_0)y_0}{x_1-x_0}
$$
实际上,即便 x 不在 x0 与 x1 之间,该公式也成立(此时为线性外插),但图像处理中不需涉及此情形。

从一维的线性插值出发,很容易拓展到二维图像的双线性插值,通过三次一阶线性插值(本质为加权求和)获得最终结果,下图便展示了该过程的定性斜视与定量俯视示意图:

二维线性插值定性斜视示意图

二维线性插值定量俯视示意图

阅读更多

求矩阵特征值与特征向量:乘幂法及其改进算法

研究背景意义

矩阵的特征值计算虽然有比较可靠的理论方法,但是,理论方法只适合于矩阵规模很小或者只是在理论证明中起作用,而实际问题的数据规模都比较大,不太可能采用常规的理论解法。计算机擅长处理大量的数值计算,所以通过适当的数值计算理论,写成程序,让计算机处理,是一种处理大规模矩阵的方法,而且是一种好的方法。乘幂法(又称幂法)是求矩阵按模最大特征值的常用方法,其结构简单、便于使用,在实际工程中应用广泛:

  • 在数值分析和优化问题中,乘幂法可通过求解矩阵按模最大特征值来得到其谱半径,从而帮助分析迭代算法的收敛性;
  • 在物理学和工程学中,特征值问题常用于分析系统的稳定性、振动频率和模态分析,乘幂法能够有效求解系统的最大特征值,从而帮助理解系统的动态行为;
  • 在图像处理中,特征值分解用于图像压缩、特征提取和模式识别,乘幂法可用于求解图像矩阵的最大特征值,从而实现高效的图像处理算法;
  • ……

但该方法也存在一定的局限性,其只适用于求矩阵按模最大的特征值,而在实际问题中往往需要求矩阵全部特征值,如在主成分分析中需要求相关矩阵的全部特征值以确定各主成分的贡献率,在求解线性微分方程组中通过求系数矩阵的全部特征值以确定其基础解系;同时该方法在求特定矩阵(如具有一对互为相反数的按模最大特征值的矩阵等)的按模最大特征值时是不收敛的。因此,我们希望以乘幂法基本思想为出发点,在此基础上提出一些改进算法以对其进行泛化,使其能够解决更为广泛且通用的应用场景下的实际问题。

算法基本思想

设n阶矩阵A具有n个线性无关的特征向量
$$
x_1,x_2,…,x_n
$$
相应的特征值
$$
\lambda_1,\lambda_2,…,\lambda_n
$$
满足:
$$
\left|\lambda_1\right|>\left|\lambda_2\right|\geq\left|\lambda_3\right|\geq…\geq\left|\lambda_n\right|
$$
现任取一非零向量u_0,作迭代
$$
u_k=Au_{k-1}, k=0,1,2,…
$$
得到向量序列{u_k}(k=0,1,2,…)。因各特征向量线性无关,故n维向量u_0必可由他们线性表示,即:
$$
u_0=\alpha_{1}x_{1}+\alpha_{n}x_{2}+…+\alpha_{n}x_{n}
$$
显然有:
$$
\begin{aligned}u_{k}&=A^{k}v_{0}=\alpha_{1}A^{k}x_{1}+\alpha_{2}A^{k}x_{2}+\cdots+\alpha_{n}A^{k}x_{n}=\alpha_{1}\lambda_{1}^{k}x_{1}+\alpha_{2}\lambda_{2}^{k}x_{2}+\cdots+\alpha_{n}\lambda_{n}^{k}x_{n}\&=\lambda_{1}^{k}\left[\alpha_{1}x_{1}+\alpha_{2}\left(\frac{\lambda_{2}}{\lambda_{1}}\right)^{k}x_{2}+\cdots+\alpha_{n}\left(\frac{\lambda_{n}}{\lambda_{1}}\right)^{k}x_{n}\right]\end{aligned}
$$

$$
\alpha_{1} \neq 0
$$

$$
\left|\frac{\lambda_{i}}{\lambda_{1}}\right|<1,i=2,3,\cdots,n
$$
可得:
$$
\operatorname*{lim}{k\to\infty}\frac{u{k}}{\lambda_{1}^{k}}=\operatorname*{lim}{k\to\infty}\frac{\lambda{1}^{k}\left[\alpha_{1}x_{1}+\sum_{i=2}^{n}\alpha_{i}\left(\frac{\lambda_{i}}{\lambda_{1}}\right)^{k}x_{i}\right]}{\lambda_{1}^{k}}=\operatorname*{lim}{k\to\infty}\left[\alpha{1}x_{1}+\sum_{i=2}^{n}\alpha_{i}\left(\frac{\lambda_{i}}{\lambda_{1}}\right)^{k}x_{i}\right]=\alpha_{1}x_{1}
$$

$$
\operatorname*{lim}{k\to\infty}\frac{\left(u{k+1}\right){m}}{\left(u{k}\right){m}}=\operatorname*{lim}{k\to\infty}\frac{\left{\lambda_{1}^{k+1}\left[\alpha_{1}x_{1}+\sum_{i=2}^{n}\alpha_{i}\left(\frac{\lambda_{i}}{\lambda_{1}}\right)^{k+1}x_{i}\right]\right}{m}}{\left{\lambda{1}^{k}\left[\alpha_{1}x_{1}+\sum_{i=2}^{n}\alpha_{i}\left(\frac{\lambda_{i}}{\lambda_{i}}\right)^{k}x_{i}\right]\right}{m}}=\lambda{1}\frac{\left(x_{1}\right){m}}{\left(x{1}\right){m}}=\lambda{1}
$$

这表明向量序列u_k具有收敛性,其收敛速度由比值
$$
\left|\frac{\lambda_{2}}{\lambda_{1}}\right|
$$
确定,该比值越小说明收敛速度越快,比值越接近于1收敛速度就越慢。

同时,该结论表明,当k取得足够大时(在实际应用时往往认为某次迭代前后误差小于设定的误差限即满足该条件),有:
$$
u_{k}≈\lambda_{1}^{k}\alpha_{1}x_{1}, \lambda_{1}≈\frac{\left(u_{k+1}\right)}{\left(u_{k}\right)}
$$
即u_ k可近似看作特征值λ_ 1对应的特征向量(较原特征向量x_ 1而言仅乘上了有限的常数系数,其结果仍为该特征值对应的特征向量),而对应的按模最大特征值λ_ 1的估计值可由前后两次迭代的特征向量u_ k相除得到。

当矩阵的按模最大特征值是重根时,上述结论仍然成立。设λ_ 1为r重根,即:
$$
\lambda_{1}=\lambda_{2}=\cdots=\lambda_{r}
$$
且满足条件
$$
\mid\lambda_{r}\mid>\mid\lambda_{r+1}\mid\geq\cdots\geq\mid\lambda_{n}\mid
$$
则有:
$$
u_{k}=A^{k}u_{0}=\lambda_{1}^{k}\left[\sum_{i=1}^{r}\alpha_{i}x_{i}+\sum_{j=r+1}^{n}\alpha_{j}\left(\frac{\lambda_{j}}{\lambda_{1}}\right)^{k}x_{j}\right]
$$
易推得(式中(u_ k)_ m表示向量u_ k的第m个分量):
$$
\lim_{k\to\infty}\frac{u_{k}}{\lambda_{i}^{k}}=\sum_{i=1}^{^{r}}\alpha_{i}x_{i},\lim_{k\to\infty}\frac{\left(u_{k+1}\right){m}}{\left(u{k}\right){m}}=\lambda{1}
$$
与一般情况略有不同的是,此时
$$
u_{k}≈\lambda_{i}^{k}\sum_{i=1}^{^{r}}\alpha_{i}x_{i}
$$
但事实上我们并没有办法在求解之前事先预知一个矩阵是否具有r重按模最大特征值,因此在实际操作的过程中采用与一般情形相同的处理方式(即认为r=1),所得的向量序列u_k仍然收敛,不影响求解结果。

基于以上的算法原理,可以编写如下MATLAB程序,实现一般情况下矩阵按模最大特征值及其对应特征向量的计算:

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
function calculatePowerMethod(matrixEdit, iterEdit)
% 获取用户输入的矩阵matrixEdit和最大迭代次数iterEdit
A = str2num(matrixEdit.Value); % 将字符串转换为矩阵
n = length(A);
V = rand(n,1); % 以随机方式初始化迭代向量u0
max_iter = iterEdit.Value; % 获取迭代次数

Eps = 1E-4; % 迭代精度
k = 0; % 初始迭代次数
lambda0 = 0;

% 乘幂法迭代,求得矩阵按模最大特征值lambda及其对应特征向量v
while k <= max_iter - 1
v = A * V;
[vmax, i] = max(abs(v));
lambda = v(i) / V(i);
V = v;
if abs(lambda - lambda0)<Eps
k = k + 1;
break;
end
lambda0 = lambda;
k = k + 1;
end
end

改进的乘幂法

在实际应用层面,上述的算法逻辑只在一小部分的常规矩阵上对于矩阵的按模最大特征值求解有较好效果。事实上,仅依托以上的代码逻辑进行求解往往会出现以下几大问题:

  1. 当矩阵A不具有n个线性无关的特征向量时(事先无法判断),乘幂法不适用。
  2. 当待求取的按模最大特征值abs(λ_ 1)>1时,迭代向量u_ k的各个分量可能会随着abs(λ_ 1)^k变得很大而使计算机“上溢”;而当待求取的按模最大特征值abs(λ_ 1)<1时,迭代向量u_ k的各个分量可能会随着abs(λ_ 1)^k变得很小使u_k成为零向量。
  3. 矩阵的按模最大特征值是一对相反数。
  4. 矩阵的按模最大特征值是一对共轭复数。

(上述算法中还给出了α_1≠0的假设,事实上如果不满足这一点也不影响乘幂法的成功使用。因为舍入误差的影响,在迭代某一步会产生u_k在x_1方向上的分量不为零,以后的迭代仍会收敛)

针对问题1,我们暂时无法提出具有针对性的解决方案,但后续的实际测试证明,当迭代次数k足够大时,我们针对问题3所提出的改进方案在该种情况下相比基本算法能够有更好的收敛性(收敛更快);针对问题2,我们可以通过将向量序列u_k进行规范化处理,限制向量的模在特定小范围内,防止计算机运算的上下溢出;针对问题3,我们在原有的乘幂法算法思想的基础上进行了改进,改进后的算法能够有效对原算法无法求解(不收敛)的按模最大特征值互为相反数的矩阵的按模最大特征值进行有效求解;针对问题4,我们目前还没有找到有效的解决方案。

迭代向量的归一化

设迭代向量u为非零向量,将其归一化得到向量
$$
y=\frac{u}{max(u)}
$$
其中max(u)表示向量u的模最大的分量(即向量的无穷范数)。这样的规范化会保证每一次迭代后得到的新的迭代向量的模最大分量均为1,这有效起到了限制迭代向量分量范围的作用,能够很好地解决上述提到的问题2。值得注意的是,对向量规范化的方式并不只有归一化这一种,实际上可以使用任意一种范数对向量进行规范化处理,如2范数等。可以证明,对于基于不同范数的归一化都有相同的向量序列收敛结论,下面以无穷范数为例给出基本的证明。(显然这样的规范化只是在原有的向量基础上除以了某一个常数,这并不会改变向量序列的收敛性)

取初始向量
$$
u_{0}\neq0
$$
规范化得
$$
y_{0}=\frac{u_{0}}{\max(u_{0})}
$$
构造向量序列:
$$
\begin{aligned}
&u_{1}=Ay_{0}=\frac{Au_{0}}{\max(u_{0})},
&y_{1}=\frac{u_{1}}{\max(u_{1})}=\frac{Au_{0}}{\max(Au_{0})}\
&u_{2}=Ay_{1}=\frac{A^{2}u_{0}}{\max(Au_{0})},
&y_{2}=\frac{u_{2}}{\max(u_{2})}=\frac{A^{2}u_{0}}{\max(A^{2}u_{0})}\
&……\
&u_{k}=Ay{{k-1}}=\frac{A^{k}u{0}}{\max(A^{k-1}u_{0})},
&\quad y_{k}=\frac{u_{k}}{\max(u_{k})}=\frac{A^{k}u_{0}}{\max(A^{k}u_{0})}
\end{aligned}
$$
结合乘幂法基本算法中已经证明的结论
$$
A^{k}u_{0}=u_{k}≈\lambda_{1}^{k}\alpha_{1}x_{1}
$$
则有:
$$
\lim_{k\to\infty}y_{k}=\frac{x_{1}}{\max(x_{1})},
\lim_{k\to\infty}\max(u_{k})=\lambda_{1}
$$
这表明此时y_ k可近似看作特征值λ_ 1对应的特征向量(较原特征向量x_ 1而言仅进行了归一化处理,其结果仍为该特征值对应的特征向量),而对应的按模最大特征值λ_ 1的估计值可近似看作未归一化前的迭代向量最大分量值max(u_k)。

基于以上的算法原理,可以编写如下MATLAB程序,实现归一化处理下矩阵按模最大特征值及其对应特征向量的计算:

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
function calculatePowerMethod(matrixEdit, iterEdit)
% 获取用户输入的矩阵matrixEdit和最大迭代次数iterEdit
A = str2num(matrixEdit.Value); % 将字符串转换为矩阵
n = length(A);
V = rand(n,1); % 以随机方式初始化迭代向量u0
max_iter = iterEdit.Value; % 获取迭代次数

Eps = 1E-4; % 迭代精度
k = 0; % 初始迭代次数
lambda0 = 0;

% 乘幂法迭代,求得矩阵按模最大特征值lambda及其对应特征向量v
while k <= max_iter - 1
v = A * V;
[vmax, i] = max(abs(v));
lambda = v(i);
V = v / lambda;
if abs(lambda - lambda0)<Eps
k = k + 1;
break;
end
lambda0 = lambda;
k = k + 1;
end
end

归一化乘幂法的进一步改进

针对问题3,从其基本情形出发(其他条件与先前保持一致),即有:
$$
\mid\lambda_1\mid=\mid\lambda_2\mid>\mid\lambda_3\mid\geqslant\cdotp\cdotp\cdotp\geqslant\mid\lambda_n\mid,\lambda_1=-\lambda_2
$$
在矩阵按模最大特征值为一对相反数的情况下,原迭代向量序列中各相邻向量的比值极限发散:
$$
\lim_{k\to\infty}\frac{\boldsymbol{u}_{k+1}}{\boldsymbol{u}k}=\lambda_1\lim{k\to\infty}\frac{a_1\boldsymbol{x}_1+(-1)^{k+1}a_2\boldsymbol{x}2+\boldsymbol{\varepsilon}{k+2}}{a_1\boldsymbol{x}_1+(-1)^ka_2\boldsymbol{x}_2+\boldsymbol{\varepsilon}_k}
$$
说明在该种情况下,采用原有的乘幂法基本算法,得到的迭代向量序列并不收敛,无法得到稳定的矩阵按模最大特征值数值求解结果。

我们在原有算法的基础上进行了一定的改进,构造了新的迭代向量序列,使其对于矩阵按模最大特征值为一对相反数的情况也能保证收敛,从而可以对该情况下的矩阵按模最大特征值进行有效求解。

阅读更多

烟雾扩散问题

1 研究背景简介

1.1 研究背景与意义

香烟烟雾中含有数千种化学物质,其中包括一氧化碳、尼古丁、苯等多种对人体有害的成分。这些物质在室内封闭环境中容易积聚,对人体健康构成显著威胁,尤其是二手烟和三手烟的危害已引起广泛关注。报告显示,2018年中国不吸烟者的二手烟暴露率为68.1%,其中家庭和工作场所是二手烟暴露的主要场所,这表明室内烟雾污染已成为影响公众健康的重要问题。因此,我们希望通过研究烟雾在室内环境中的扩散规律,为烟雾的控制、空气污染防治或室内空气质量管理提供参考,并帮助优化通风设计或制定健康防护措施。

烟雾的扩散过程受到室内温湿度、气流模式、房间结构及家具布置等多种因素的影响,具有较高的复杂性和随机性。深入研究烟雾扩散的传输机制,可以帮助揭示其污染范围与浓度分布,为优化室内空气质量管理提供理论支持。但在估计和预测吸入暴露风险时,由于与生物伦理学和动物保护相关的潜在限制,涉及人类志愿者和其他用于毒理学研究的哺乳动物替代模型的体内研究存在局限性。出于这样的考虑,我们希望通过理论分析建模与数值模拟的方式,得到烟雾扩散的一般规律,从而为提出可能的防控手段提供理论依据。

通过实验和仿真研究,能够验证不同通风方案对烟雾扩散的控制效果,为改善居住环境提供技术支持;利用数值模拟,可以精确再现不同环境下烟雾的扩散过程,从而更直观地评估各类干预措施的有效性。这种方法不仅降低了研究成本,还能为制定更加科学、精确的室内空气污染防控策略提供强有力的支持。

图1.1:烟草烟雾中的有毒有害物质

图1.2:长期吸入二手烟对人体健康的危害

1.2 研究目标

本研究旨在探讨室内封闭环境下烟雾的扩散特性,基于扩散方程等物理原理与数学物理方法对烟雾的扩散情况进行解析求解与数值模拟,重点分析烟雾的流动路径、扩散速率和浓度分布,以优化空气管理和烟雾控制策略。

在具体的研究过程中,我们主要采用特定尺寸的密封容器来模拟室内封闭环境以便于实验开展与现象观察;同时,我们的研究主要关注扩散过程中烟雾的扩散效果、扩散速度以及不同时刻的浓度分布这三个要素,并通过定量计算测量与定性观察现象相结合的方式,得到烟雾扩散浓度空间分布随时间变化的的一般数学物理规律,从而为设计室内烟雾浓度控制系统提供理论依据。

图1.3 研究区域示意图

2 理论分析求解

2.1 研究对象

在实际研究过程中,为方便实验的开展,我们选择了粒径分布在0.1~10微米范围内的植物甘油(丙三醇)气雾作为研究对象,这也是电子烟烟雾的主要成分之一。之所以使用植物甘油气雾来代替香烟烟雾进行研究,主要出于以下考量:

  • 安全性:植物甘油为食品级材料,无健康与环境污染风险

  • 可控性:植物甘油气雾生成过程可控,可进行定量化分析

  • 易获取性:价格低廉,易于获取

  • 可重复性:物质纯度高,化学性质稳定

具体而言,植物甘油气雾具有以下几条显著的理化特性:

  • 无色无臭,有甜味,极易溶于水

  • 密度(25℃):1.26 g/cm^3

  • 分子量: 92.09 g/mol

  • 主要粒径属于典型气溶胶粒径范围

  • 挥发性极低,以小颗粒悬浮于空气中

在研究过程中进行这样的材料替换,具有如下的合理性:

  • 植物甘油气雾与香烟烟雾的气溶胶形成机制相同(蒸发-冷凝),二者在扩散和湍流行为上具有共性

  • 二者粒径分布相似,具备相似的扩散动力学特征

  • 二者在扩散过程中的视觉效果接近,便于追踪扩散行为

在本研究的理论分析部分,重点关注植物甘油气雾的浓度(即单位体积中该种物质颗粒的质量)ρ(x, y, z, t)这一物理量在研究区域(长为x_0 = 40cm,宽为y_0 = 50cm,高为z_0 = 60cm的长方体规则区域)空间范围内的分布情况及其随时间的变化情况。

2.2 数学物理方程的导出

针对烟雾扩散这一常见现象,有现成的实验规律——菲克定律(又称扩散定律)可以直接使用,其基本公式如下:

$$
\overrightarrow{q} = - D\nabla\rho
$$
其中:

  • 式中负号代表扩散转移的方向(浓度减小的方向)和浓度梯度(浓度增大的方向)相反;
  • D:扩散系数,与物质的种类以及环境温度有关;
  • ∇ρ:浓度梯度,描述浓度不均匀分布的程度;
  • 扩散流强度,即单位时间通过单位(横截)面积的质量,描述扩散运动的强度:

$$
\overrightarrow{q} = \frac{dm_{g}}{dVdt}
$$
在本研究中,针对常温环境(25℃)下植物甘油气雾在空气中的扩散系数,可进一步通过Chapman-Enskog方程
$$
D_{AB} = \frac{0.00143 \times T^{1.75} \times \sqrt{\frac{1}{M_{A}} + \frac{1}{M_{B}}}}{P \times \sigma_{AB}^{2} \times \Omega_{D}}
$$
进行估算,代入空气的平均分子量28.97 g/mol和估计的分子直径0.5nm可计算得到此时的扩散系数约为:
$$
D = 0.0962{cm}^{2}/s
$$
由于我们的研究区域是一个长方体的三维规则区域,故在研究坐标系的选择上,以长方体区域的底端顶点为原点,长、宽、高延伸方向作为$x、y、z$正方向建立空间直角坐标系,原点在长方体上的对角顶点坐标为$(x_{0},\ y_{0},z_{0})$。针对三个不同方向,还可以进一步地给出菲克定律的分量形式:

阅读更多

基于自编码器和卷积网络的肺炎图像识别

1 项目背景与研究意义

1.1 项目背景

肺炎作为一种常见的呼吸系统疾病,对人类健康构成了长期威胁,特别是随着COVID-19新冠肺炎疫情的全球爆发,其公共健康影响更为显著。COVID-19肺炎具有传播速度快、感染范围广、诊断难度大的特点,对全球医疗系统和社会经济产生了深远影响。特别是在疫情高峰期,医疗资源的短缺和诊断效率的瓶颈,进一步突显了快速、准确诊断工具的重要性。

传统肺炎诊断方法主要依赖医生对胸部X光片或CT图像的人工分析,既耗时又容易受到经验和疲劳的影响,尤其在COVID-19疫情期间,大量影像数据的涌现使得人工诊断难以满足需求。与此同时,COVID-19的影像表现与其他类型肺炎的重叠性增加了诊断的复杂性,这进一步加剧了对智能化诊断系统的需求。

随着人工智能技术的快速发展,深度学习为医疗影像分析带来了全新的解决方案。卷积神经网络(Convolutional Neural Network, CNN)凭借其强大的图像特征提取能力,在自动化诊断中展现了巨大潜力。同时,由于不同医疗机构的CT扫描设备性能差异显著,特别是在医疗资源较为匮乏的地区,CT影像常常受到设备老化、分辨率低或操作不规范等因素的影响,图像质量参差不齐,这不仅增加了诊断的复杂性,还对自动化系统的鲁棒性提出了更高要求;而自编码器(Autoencoder)作为一种有效的降噪工具,为医疗影像数据预处理提供了重要支持。通过自编码器的引入,可以有效消除图像中的噪声干扰,减少不同设备间的成像差异,为后续的分类和识别模型提供高质量的输入数据。因此,本项目提出结合自编码器和卷积神经网络的深度学习框架,开发一套针对肺炎(包括COVID-19)CT影像识别的智能诊断系统。

图1.1:新冠肺炎疫情概况(主要症状、防治措施与传播状况)

图1.2:新冠肺炎患者的肺部CT影像

1.2 研究意义

本项目以新型冠状病毒肺炎为切入点,面向未来医学智能化需求,开发的诊断系统不仅能够应对当下疫情挑战,还具有推广至其他医学影像诊断场景的潜力,从而为全球公共健康事业的发展提供有力支持。

面向新冠肺炎疫情期间大规模肺部影像数据的快速诊断需求,本系统依托深度学习技术,有效提升了诊断效率,为疫情防控和患者管理提供重要的技术支持。通过先进的模型算法,系统能够精准识别肺部CT影像中的病变特征,减少人为误差,确保诊断结果的准确性和一致性,大幅降低不同医疗机构和医生之间的诊断差异,避免误诊和漏诊风险,从而更好地保障患者安全。

针对基层医院或偏远地区医疗资源匮乏的现状,本系统可作为一种可靠的辅助诊断工具,为医生提供科学的决策支持,帮助缓解诊断能力不足带来的压力。其高效的处理能力不仅提高了基层医疗服务水平,也为疫情防控的全面推进提供了技术保障,为应对紧急医疗需求的地区解决实际困难。

此外,本系统在高效处理和分析海量肺部CT影像数据的基础上,还为研究新冠肺炎的病理特征及流行规律提供了宝贵的数据支持。这些分析结果可进一步应用于疫情传播趋势预测和公共卫生政策制定,为疫情防控策略的科学性和有效性奠定了坚实基础。

同时,本系统也为患者病情的动态管理提供了重要帮助。通过智能分析新冠肺炎影像特征的变化趋势,系统能够为临床医生提供精确的病情评估建议,有助于及时调整治疗方案。这种基于影像数据的技术支持,不仅提高了患者管理的科学性和有效性,还为医疗资源的合理分配提供了重要依据,进一步推动了疫情防控工作的高效开展。

2 数据集获取与预处理

2.1 数据集介绍

本项目使用的肺部X-光片数据集从Kaggle网站(链接:https://www.kaggle.com/datasets/alsaniipe/chest-x-ray-image)获取,共分为三类标签:新冠肺炎COVID19、正常NORMAL和普通肺炎PNEUMONIA,该数据集已经事先划分好了训练集与测试集。此外,为测试模型对于不同质量CT影像的识别精度,还对测试集中的部分图像使用高斯噪声进行扰动,以模拟实际CT扫描的成像质量差异。

图2.1:肺部CT影像数据集概况
图2.2:肺部CT影像数据集概况

图2.3:数据集中部分肺部CT影像展示(上行为训练集(干净),下行为含噪声测试集)

数据分布如下表所示:

表2.1:数据集数据分布情况

COVID19 NORMAL PNEUMONIA
Train 460 1266 3418
Test 116 317 855
Noisy_Test 26 20 20

2.2 编程环境搭建

本项目中所有的代码编写与运行均是在配备NVIDIA GeForce RTX 3060显卡、16GB运行内存、12th Gen Inter(R) Core(TM) i7-12700@2.10GHz处理器与Microsoft Windows 11操作系统的工作站上使用Python编程语言完成的。

软件环境方面,采用Conda进行环境管理,在控制台中通过命令”conda create -n covid python=3.12”创建虚拟环境,并在激活环境后使用pip install命令依次安装所需的各种依赖库;全部安装并测试完成后,通过命令”pip freeze >
requirements.txt”将虚拟环境中安装的所有依赖库及对应版本写入文件requirements.txt,后续移植时可在新的运行环境中运行命令”pip install -r requirements.txt”完成环境的一键配置。

值得注意的是,在PyTorch(包括torch、torchvision与torchaudio库)安装时需要根据自己电脑使用的CUDA版本(使用CPU则直接在命令行中使用pip install安装即可)在PyTorch官网中找到对应的安装命令进行安装。我使用的CUDA版本为12.6,安装命令的选取如下图所示:

阅读更多

心电信号采集与处理

1 实验需求分析

1.1 项目背景介绍

心电信号(Electrocardiogram, ECG)是反映心脏活动电生理变化的重要生物电信号,其特征包括心率、节律、波形等参数,能够直观反映心脏健康状况,在临床医学、健康监测和疾病预防中具有不可替代的作用。通过心电信号的测量与分析,可以检测心律失常、心肌缺血、心脏传导阻滞等异常,为心脏疾病的诊断和治疗提供关键支持;借助便携式和可穿戴设备,实时心电监测已成为健康管理的重要手段,为心血管疾病高危人群提供预警,有助于降低发病率和致死率。此外,心电信号还是生物医学研究的重要工具,为心血管药物开发、人工心脏研究等领域提供了基础数据。在当前人口老龄化加剧和心血管疾病高发的背景下,心电信号测量与分析技术显得尤为重要。本项目旨在开发高精度的心电信号采集系统,结合课程中介绍的数字信号处理等专业知识,为心脏健康提供更加便捷和智能的监测方案,推动精准医疗与个性化健康管理的发展。

1.2 心电信号特征与设计需求

心脏内部产生的一系列非常协调的电刺激脉冲,使得心脏肌肉细胞有节奏的舒张和收缩,这些信号传递到人体表面的不同部位形成不同的电位差。通过仪器设备可以从体表检测到这些微弱的电位差信号,称之为心电信号。换言之,心电信号即为人体心脏细胞细胞膜产生的电势差。在医学上,医生往往需要通过心率与幅值等参数来初步判断患者的健康状况,因此实现高精度的心率与幅值测量是本项目中设计的心电信号采集与处理系统的核心功能。

图1.1:心电信号简介

正常的心电信号频率范围为0.05Hz-100Hz,其能量集中在低频段,其中99%的能量集中在0Hz-35Hz。在其采集过程中容易受到各种干扰,主要分为三种:

  • 工频和工频的谐波频率干扰,工频频率在我国为50Hz;

  • 肌颤噪声和采样电路参考电压引入的电源纹波等高频噪声,频率通常在100Hz以上;

  • 呼吸基线漂移和采样引入的直流分量,频率一般分布在0-0.7Hz。

以上的各种干扰会对心电信号采集结果产生较大的影响,使得采集到的心电信号中出现许多杂波与噪声,这是我们所不希望看到的。因此,为提高心电信号的测量精度,需要设计相应的滤波器对传感器采集到的信号进行滤波,从而减小信号中的噪声震荡,提高心率与幅值测量的准确程度。特别的,由于参考电压受环境温度变化会产生一定的温漂,以及人的呼吸活动和电极滑动也导致基线漂移。这些干扰的频率很低,通常在几Hz以内,但和心电信号的有效频谱非常接近,因此需要过渡带较窄的IIR直流陷波器来消除干扰。

基于心电信号的以上特性,对于该心电信号采集与处理系统,提出如下的技术指标需求:

  • 0频处的缓变直流衰减不低于30dB;

  • 降噪滤波器以35Hz为3dB通带截止频率,过渡带不超过10Hz,阻带衰减不低于40dB;

  • 心率估算误差不超过10%。

2 实现方案论证

2.1 系统框架设计

本项目的核心目标是实现心电信号的采集与滤波以及心率测量,同时需要在屏幕上绘制时域波形与频谱图。具体而言,细分的功能如下:

  • 实现ADS1292获取心电信号原始数据,并通过串口传输至PC电脑;

  • 实现PC电脑中通过MATLAB对原始数据进行时域和频域分析;

  • 实现PC电脑中通过MATLAB对原始数据进行降噪和提取心率;

  • 实现STM32单片机中对原始数据进行降噪和提取心率;

  • TFT屏幕中绘制心电信号曲线和显示心率数值。

为实现以上功能,采用如下的系统设计流程:

  1. 调试ADS1292R_PowerOnInit函数中的ADS1292芯片读取,通过读取芯片device_id验证硬件功能正常且连接正确;

  2. 在中断驱动下,读取ADS1292的原始数据,并存储在单片机的存储器中;

  3. 把原始数据传输到PC;

  4. 在PC中分析原始数据的时域和频域;

  5. 在PC中设计滤波器对原始数据进行处理,并提取心率等;

  6. 把PC中的滤波器移植到单片机中;

  7. 在单片机中把心电波形和心率等数据显示到TFT屏幕。

图2.1:系统设计流程

根据如上设计流程,结合目前提供的材料,设计了如下图所示的心电信号采集与分析系统:

图2.2:系统框架

系统的工作流程如下:

  1. 首先,STM32控制器向心电传感器发送采集指令,传感器随后采集来自人体或模拟信号源的心电信号,并将数据反馈至控制器;

  2. 接着,控制器将采集到的数据传输至PC端,供进一步分析处理;

  3. 然后,根据PC端的分析结果,控制器会调整参数并优化心电信号处理;

  4. 最终,处理后的结果将在TFT屏幕上实时显示,供用户查看。

可以看到,该系统主要涉及到STM32主控芯片、ADS1292R传感器、TFT显示屏、心电信号模拟器以及PC端分析软件MATLAB等关键组件。接下来将对于本项目涉及的各硬件组件进行介绍。

2.2 STM32主控芯片

本项目选用的微控制器STM32F407ZG是系统的核心控制单元,负责协调各个模块的工作。其不仅负责信号的采集,还管理信号传输、滤波器应用、以及与TFT屏幕的显示操作。其强大的处理能力和灵活的控制方式使其成为整个系统的”大脑”。该控制器目前搭载在”正点原子”探索者STM32F407开发板V3上,负责完成系统的信号采集、处理与传输任务。

阅读更多

基于直流电源调控的自动调光控制设计

摘要

本项目围绕直流电源调控的自动调光控制系统展开研究与设计,系统性地探讨了Buck变换器的基本原理、建模方法、性能分析及其实验验证过程。在硬件设计方面,基于STM32处理器,选择了高性能的元器件并通过合理的电路拓扑实现高效的能量转换;在软件控制算法方面,采用PID闭环控制,并结合自动控制原理中的经典控制理论,利用PSIM与MWorks等仿真与科学计算工具,对控制系统的时域响应、频域特性和稳定性进行了详尽分析,进而通过参数优化与校正环节设计显著提升了系统的响应速度和稳态性能,同时也验证了闭环控制系统在动态性能、抗干扰能力和输出精度方面的显著优势。此外,通过实验测量与仿真结果对比,探讨了电路寄生参数对系统性能的影响,为后续优化提供了理论依据。在基于光敏电阻的自动调光功能模块中,结合蓝牙通信接口实现了系统的智能化控制,同时对于自动调光系统进行外观设计,赋予产品更多的人文关怀与实用价值;在光伏板最大功率点跟踪(MPPT)功能模块中,根据MPPT的原理与基本思想设计了相应的控制算法,并在实验中成功控制光伏板输出功率,使其约等于负载消耗功率,完成了不同光照强度下最大功率点的跟踪。最后,对于该自动控制系统的设计成果及其在实际应用中的可行性与局限性进行总结,并对未来可能的优化方向和工程实现前景提出了展望。

关键词:Buck变换器;PID闭环控制;自动调光;光伏MPPT

1 课程涉及理论基础和STM32简介

1.1 自动控制原理简介

在科学技术飞速发展的今天,自动控制技术和理论已经成为现代社会不可缺少的组成部分。自动控制技术的应用不仅使生产过程实现自动化,从而提高了劳动生产率和产品质量,降低了生产成本,提高了经济效益,改善了劳动条件,使人们从繁重的体力劳动和单调重复的脑力劳动中解放出来;而且在人类征服大自然、探索新能源、发展空间技术和创造人类社会文明等方面都具有十分重要的意义。

自动控制理论是研究关于自动控制系统组成、分析和综合的一般性理论,是研究自动控制共同规律的技术科学。自动控制是在人不直接参与的情况下,利用外加的自动控制设备或装置(控制装置或控制器),使机器、设备或生产过程(统称为被控对象)的某个工作状态或参数(被控量)自动地按照预定的规律运行,使机器的动作、设备的运转、生产过程的状态能够自动地在一定的精度范围内按照给定的规律变化。学习和研究自动控制理论是为了探索自动控制系统中变量的运动规律和改变这种运动规律的可能性和途径,为建立高性能的自动控制系统提供必要的理论依据。

1.2 本项目所涉及的经典控制理论内容

图1.1:项目涉及的经典控制理论框图

本项目从经典控制理论的基本原理与概念出发,以Buck变换器这一单输入-单输出的线性系统作为研究对象,利用微分方程、Laplace变换与传递函数等数学工具建立系统的数学模型,并基于时域分析、频域分析以及根轨迹法等多种分析方法对于系统的稳定性与响应特性进行详细分析,从而针对特定的性能指标进行对应的校正设计,通过引入PID控制器并调控其参数以改变系统的频率特性从而满足给定的各项性能指标,使得整个闭环控制系统能够兼具稳定性、快速性与准确性。

1.3 STM32处理器介绍

控制核心是控制系统中的重要组成部分,用于计算、解析各种数据,并执行相应的控制算法。芯片选型的设计直接决定了控制板的性能和功能。STM32是由意法半导体公司(ST)推出的基于Arm Cortex-M处理器内核的32位微控制器,专为要求高性能、低成本、低功耗的嵌入式应用设计,集实时功能、数字信号处理、低功耗/低电压操作、连接性等特性于一身,同时还保持了集成度高和易于开发的特点,基于行业标准内核,提供了大量工具和软件选项以支持工程开发,非常适用于小型项目或端到端平台。

本项目选用的处理器STM32F103C8T6作为中等容量高性能系列MCU,集成了工作频率为72MHz的高性能Arm Cortex-M3 32位RISC内核、高速嵌入式存储器(高达128KB的Flash存储器和20KB的SRAM存储器),以及大量连接至2条APB总线的增强型I/O与外设,具有36引脚至100引脚等6种不同的封装类型。所有器件均提供2个12位ADC、3个16位通用定时器、2个PWM定时器以及标准和高级通信接口:多达2个I2C和SPI、3个USART、1个USB和1个CAN。器件的工作电压为2.0V至3.6V。该处理器的工作温度范围为-40℃到+85℃,可扩展至-40℃到+105摄氏度。这些特性使得该处理器成为各种应用的理想之选,也能很好满足本项目对于控制器的性能需求。

图1.2:本项目选用的处理器STM32F103C8T6

1.4 本章小结

本章主要介绍了本课程相关的自动控制理论基础,针对本项目涉及到的经典控制理论框架进行了简要概述,同时对于本项目所选用的控制核心——STM32处理器进行简单介绍,重点分析了我们采用的STM32F103C8T6处理器的性能特性并给出选型原因。这为本课程项目提供了整体框架,并从理论上对后续项目的具体实施给出了方向性的指引。

2 直流Buck变换器设计与调试

2.1 Buck变换器拓扑原理分析

Buck(降压式)变换器是一种输出电压≤输入电压的非隔离直流DC-DC变换器,其中输入电流为脉冲式的,而输出电流为连续的低纹波直流电压。Buck变换器实现的稳态输入输出关系为:
$$
U_{0} = DU_{in}
$$
Buck变换器的主电路由开关管Q,二极管D,输出滤波电感L和输出滤波电容C构成。

图2.1:Buck开关功率变换器基本电路

可以看到,在能量缓冲变换电路中,主要由如下三个部分组成:

  1. 电感L与电容C实质上构成了一个二阶低通滤波器,通过滤除开关频率交流分量而仅保留其直流分量,得到平直的输出电压U0;

  2. 脉冲宽度调制(Pulse Width Modulation,PWM)产生方波电压控制开关管Q的导通;

  3. 二极管D为电感电流提供续流回路。

Buck变换器主电路整体的工作逻辑如下:

  1. 当开关管Q驱动为高电平时,开关管导通,储能电感L被充磁,流经电感的电流线性增加,同时给电容C充电,给负载R提供能量;

图2.2:开关管导通时电流环路

阅读更多

基于STM32F407实现的信号发生与采集分析系统

演示视频已上传至Bilibili视频平台:https://www.bilibili.com/video/BV1wUiRYxE8z


一、系统功能与整体架构设计

系统实现功能

(1)单片机在按键控制下,产生1kHz的正弦波或方波;

(2)单片机能够采集波形,并且显示;

(3)单片机能够分析采集波形的频谱,并且显示频谱与基波频率。

整体架构设计图

系统主页与按键对应功能简介

每次启动系统都会默认直接进入该主页面:

(1)蓝色部分的文字为系统名称与作者姓名,这会在后续的每个功能页面中都有显示;

(2)黑色部分的文字为各按键对应的功能介绍。

正如主页的功能介绍栏所示:

(1)按下KEY0:PA4引脚开始持续输出1kHz的正弦波信号,并在屏幕上实时显示从PA5引脚采集到的输入信号波形;

(2)按下KEY1:PA4引脚开始持续输出1kHz的方波信号,并在屏幕上实时显示从PA5引脚采集到的输入信号波形;

(3)按下KEY2:在屏幕上实时显示从PA5引脚采集到的输入信号的频谱分析结果(幅值谱,频率范围为0~1000Hz);

(3)按下KEY3(KEY_UP):在屏幕上实时显示从PA5引脚采集到的输入信号的频谱分析结果(幅值谱,频率范围为0~8000Hz)。


二、各部分功能实现

1、1kHz正弦波与方波的产生

模块功能架构设计

在实际单片机编程实现时,导入并调用DSP库加速信号数组(正弦波)的计算,并通过时钟TIM6(分频)控制DMA的数据搬运过程,并设置DAC数模转换将搬运后的信号数字数据在PA4引脚以模拟信号形式输出。

阅读更多

机器学习分类算法项目

摘要

本项目围绕机器学习分类算法展开, 以支持向量机(support vector machine,SVM)为主要研究对象,探究其分类性能、模型改进与优化算法。SVM和Logistic回归模型都可以用于解决二分类问题,但模型设计的思路不同,因此希望能够比较两者在分类性能上的差异。项目过程中代码完全基于R语言实现,主要以二维样本数据为研究对象,生成模拟数据并基于经典硬间隔SVM模型和Logistic回归模型分别进行建模与训练,在测试集上对模型进行验证,最终比较两者的分类效果差异。实验结果表明,当样本数据本身区分度不明显时,两种分类模型效果均较差,但Logistic模型明显优于经典硬间隔SVM;当样本数据本身具有明显的差异性时,两种分类模型效果均较好,SVM略优于Logistic。此外,还对改进后的SVM模型(核函数由线性函数更换为高斯核函数)进行性能测试,发现其在区分度不明显的数据集上显著优于经典硬间隔SVM,说明其显著提升了其在非线性可分数据上的分类效果;但在区分度较明显的数据集上分类效果反而略逊于经典SVM模型。最后,对两篇有关SVM改进模型的文献进行了阅读与调研,总结了软间隔SVM模型在正则项和损失项拓展方面的研究进展,并介绍了柔性套索惩罚和快速截断Huber损失等改进方法。

关键词: 机器学习分类算法、二分类、支持向量机(SVM)、Logistic回归、硬间隔、软间隔、高斯核函数、改进的SVM模型、柔性套索惩罚、快速截断Huber损失、R语言

项目概述

问题背景

人工智能的概念是在1956年首次被提出,其目标旨在希望通过计算机模拟人的思维能力或智能行为,从而让计算机能够像人类一样进行思考。目前,人工智能已经在机器翻译、智能控制、图像识别、语音识别、游戏博弈等领域得到广泛的应用。

机器学习作为人工智能的一个发展方向,起源于20世纪50年代的感知机数学模型,其目标是使得机器能够像人类一样具有学习能力。机器学习的基本过程主要是基于样本数据(客体)去训练/学习某个模型或决策函数(主体)。一般而言,正则化框架下的机器学习过程主要由学习机、损失项和正则项(惩罚项)三个部分构成,最终通过学习得到模型。

支持向量机(support vector machine,SVM)最早由Cortes和Vapnik二人于1995年为解决二分类问题而提出[^1]。作为经典的机器学习模型之一,SVM有坚实的统计理论基础,算法实现容易,且决策函数具有很强的几何含义。由于其在模式识别等数据分析问题中的优越表现,SVM如今已成为最经典的判别分析方法之一。与SVM相类似,广义线性回归统计模型中的Logistic回归模型同样也可用于解决二分类问题。本质上来说,两种方法都注重研究一组协变量X_1, …, X_p是如何影响二元的响应变量Y的,在用途上具有极大的相似性,因而希望研究并比较两者分类效果的差异性。

除此之外,SVM作为一种经典且基础的机器学习算法,在漫长的发展历程中也经历了多次迭代,有多种多样的改进版本。最基本的版本为硬间隔SVM,但由于实际的样本数据很可能不满足线性可分的理想情况,又发展出了采用不同求解算法的软间隔SVM模型以及基于核函数升维思想实现的非线性SVM,基于软间隔SVM模型又集中在模型损失项与正则项两个方面进行了理论上的拓展。这样的发展是永无止境的,在此希望对过去的部分研究改进成果进行理论总结与代码实现,以更好地了解SVM模型的发展现状。

项目任务

在本次项目中,需要随机生成模拟数据,并在该样本数据基础上分别利用经典SVM模型与Logistic模型进行统计建模,同时对比两者的分类效果;此外还需要总结并实现部分改进版本的SVM算法,分析其预测效果。具体而言可细分为如下任务:

  • 任务1:随机生成200条模拟数据并将其分为训练数据集与测试数据集,利用训练数据集分别基于经典硬间隔SVM模型与Logistic广义线性回归模型建立统计模型,实现样本数据的分类且在测试数据集上进行验证,比较两者的分类效果差异。

  • 任务2:代码实现某一种改进版本的SVM模型,简单测试其性能并将其分类结果与经典版本进行对比。

  • 任务3:查阅SVM模型改进相关的文献,基于正则化框架对于文献中涉及的模型(学习机、损失项、正则项)、创新点与求解算法进行重述与总结。

项目过程

本项目代码部分完全基于R语言实现,主要涉及样本模拟数据的生成,以及SVM(经典与改进版本)与Logistic回归模型的建立、训练与测试。

模拟数据生成

本项目中涉及到的样本数据完全由模拟方法生成。具体而言,不论是SVM还是Logistic回归模型,其目的都是为了研究一系列协变量对于一个二元的响应变量的影响。为方便起见,选择采用协变量的维度为二维,即二元响应变量Y只由两个变量X_1, X_2决定。在生成数据时,为了较好地区分出两类数据,分别在正态总体下以均值为0和均值为1生成两组模拟数据(同一条数据中的两个变量X_1, X_2来自同一均值的总体),并分别打上分类标签(即对应Y的取值为)0或1:

1
2
3
4
5
6
7
8
9
10
11
12
set.seed(123) #设置随机种子,固定每次运行程序生成的随机数,使结果可重复
n <- 200 # 每个类别的数据点数

# 生成类别0的数据
x1 <- matrix(rnorm(n * 2, mean = 0), ncol = 2)
y1 <- rep(0, n)
# 生成类别1的数据
x2 <- matrix(rnorm(n * 2, mean = 1), ncol = 2)
y2 <- rep(1, n)
# 合并数据
x <- rbind(x1, x2)
y <- c(y1, y2)

绘制样本点对应的散点图,初步观察其分类情况:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 加载 ggplot2 包
library(ggplot2)

# 创建数据框
data <- data.frame(x1 = x[, 1], x2 = x[, 2], y = factor(y))

# 设置点的大小和透明度
p <- ggplot(data, aes(x = x1, y = x2, color = y)) +
geom_point(size = 3, alpha = 0.7) + # 调整点的大小和透明度
scale_color_manual(values = c("blue", "red")) +
labs(x = "x1", y = "x2", color = "Class") +
theme_minimal()

# 调整背景和边界线
p + theme(panel.background = element_rect(fill = "white", color = "black"),
panel.border = element_rect(color = "black", fill = NA),
axis.line = element_line(color = "black"))

ggsave("2.png", plot = p, width = 6, height = 6, units = "in", dpi = 300)

观察上左图可知,由于基于正态总体生成模拟数据时仅制定了均值而未指定方差(默认为1),导致令均值为0和1的情况下两类数据没有办法明显的区分开来,这样的分类效果显然是不好的。经过调试,当设置两类数据均值分别为0和5时,数据点呈现良好的区分性(如上右图所示)。

为便于后续的模型训练,还需要将样本模拟数据分成训练集与测试集两部分,根据经验,较为合适的数据集数量比例为7:3,即样本数据中的70%为训练集,另外30%为测试集用于验证。

1
2
3
4
5
6
7
8
9
10
# 将数据分为训练集和测试集
train_index <- sample(1:(2 * n), 0.7 * 2 * n)
x_train <- x[train_index, ]
y_train <- y[train_index]
x_test <- x[-train_index, ]
y_test <- y[-train_index]

# 合并
train_data <- cbind(x_train, y_train)
test_data <- cbind(x_test, y_test)

在此对部分训练集数据进行罗列:

阅读更多

产品质量管理项目

摘要

本项目的核心任务是通过统计过程控制(SPC)方法,对某工厂生产的滚珠直径数据进行产品质量管理,评估产品工艺水平及其生产过程是否受控。统计过程控制作为一种基于概率统计的过程控制方法,自1924年由Shewhart博士提出控制图以来,已广泛应用于现代制造过程的质量控制中。本项目基于Matlab软件开发,对于收集到的数据,通过描述性统计分析、正态性检验、总体均值检验、工序能力指数计算与绘制均值控制图和方差控制图等多种方式,对数据进行全面分析,最终评估工艺水平及生产过程的受控状态。具体而言,首先,在数据收集过程中,结合实际数据与模拟数据,得到25组产品质量样本数据(每组至少5个样本);随后,通过描述性统计分析方法对数据进行宏观的认知,根据均值、方差、极差、直方图等指标对数据进行初步分析;接着又利用假设检验的方法,分别通过Pearson卡方检验与t检验等方法验证数据是否符合正态分布,并对其总体均值进行检验。基于对于正态总体及其均值、方差的检验合理性,最终计算并评估了数据的工序能力指数,同时绘制了均值控制图和方差控制图,以直观反映生产过程中的数据波动情况。通过多种方法的综合分析,最终得出了工厂生产的滚珠直径的工艺水平评价和生产过程的受控状态判断。

关键词: 产品质量管理、统计过程控制(SPC)、假设检验、Shewhart控制图、Matlab

项目概述

问题背景

现代产品质量管理主要有两个核心目标:第一,评价产品的工艺水平如何,即产品质量如何;第二,评价产品的生产过程是否受控,即产品可靠性如何。从现代质量控制的角度看,一方面要求产品质量好,另一方面还要求可靠性高。

统计过程控制(Statistical Process Control, SPC)是一种基于概率统计的过程控制方法。1924年美国贝尔实验室的Shewhart博士提出控制图,标志着产品统计质量控制的正式起点。作为现代质量管理的重要方法,SPC广泛应用于现代制造过程的质量控制。20实际80年代,国际上半导体制造过程已经普遍采用SPC技术提升产品合格率和可靠性。比如Motorola公司提出并在美国通用电器公司等广泛应用的6σ管理,其主要技术基础就是SPC理论。

生产过程是否处于统计受控状态,取决于生产过程是否存在异常因素导致产品质量的起伏变化。产品加工结果是否满足加工规范要求,反应的是工艺水平的高低;而工艺是否受控,反应的是生产过程是否存在异常因素。

项目任务

在本次项目中,需要收集批量产品质量数据,利用SPC方法对其进行管理,分析整体工艺水平并判断生产过程是否处于统计受控状态,具体而言可细分为如下任务:

  • 任务 1:收集或生成25组以上的数据,每组至少5个样本。

  • 任务2:根据均值,方差,极差,直方图等指标,对数据进行描述性统计分析。

  • 任务 3:对数据进行正态性检验与总体的均值检验。

  • 任务 4:计算数据工序能力指数并对其进行评估。

  • 任务 5:描绘均值控制图和方差控制图。

  • 任务 6:得出结论:工艺水平如何;生产过程是否处于统计受控状态。

项目过程

本项目完全基于Matlab代码实现SPC方法进行产品质量管理。

数据收集

本项目中的数据收集采用实际数据与模拟数据结合的方式,其中实际数据以书本7.4节的例题7.4.4[^1]为主要来源,在此基础上利用生成的模拟数据对其进行扩充,最终得到25组产品质量样本数据,每组中含有5个数据。

具体而言,本项目的问题情境为对工厂生产的滚珠直径(单位:$mm$)进行产品质量管理。书本上的例题提供了50个直径数据,将其作为扩充生成模拟数据的源数据source_data,即:

1
2
3
4
5
6
7
8
9
10
source_data=[15.0,15.8,15.2,15.1,15.9,
14.7,14.8,15.5,15.6,15.3,
15.0,15.6,15.7,15.8,14.5,
15.1,15.3,14.9,14.9,15.2,
15.9,15.0,15.3,15.6,15.1,
14.9,14.2,14.6,15.8,15.2,
15.2,15.0,14.9,14.8,15.1,
15.5,15.5,15.1,15.1,15.0,
15.3,14.7,14.5,15.5,15.0,
14.7,14.6,14.2,14.2,14.5];

设置扩充后的数据组数num_groups以及各组样本数据个数samples_per_groups:

1
2
num_groups = 25;
samples_per_group = 5;

两者相乘得到样本数据总数num_data_points:

1
num_data_points = num_groups * samples_per_group;

要对原始数据进行扩充,首先需要复制原始数据并添加随机扰动:

1
2
replicated_data = repmat(source_data, 1, ceil(num_data_points / length(source_data)));
perturbed_data = replicated_data(1:num_data_points) + 0.05 * randn(1, num_data_points);

接着使用插值生成更多数据点,并保留一位小数:

1
2
3
4
x = 1:length(perturbed_data);
xi = linspace(1, length(perturbed_data), num_data_points);
interpolated_data = interp1(x, perturbed_data, xi, 'spline');
interpolated_data = round(interpolated_data, 1);
阅读更多