既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上物联网嵌入式知识点,真正体系化!
由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、电子书籍、讲解视频,并且后续会持续更新
需要这些体系化资料的朋友,可以加我V获取:vip1024c (备注嵌入式)
2
Z
3
{X_{t-2}} = \sqrt {{{{a}}_{t-2}}} {X_{t - 3}} + \sqrt {1 - {{{a}}_{t-2}}} {Z_3}
Xt−2=at−2
Xt−3+1−at−2
Z3 ——公式5
同理,我们将公式5代入到公式4中,得到
x
t
x_t
xt时刻图像和
x
t
−
3
x_{t-3}
xt−3时刻图像的关系,公式如下:
X
t
=
a
t
a
t
−
1
a
t
−
2
X
t
−
3
1
−
a
t
a
t
−
1
a
t
−
2
Z
^
3
X_t=\sqrt {a_ta_{t-1}{a_{t-2}}}X_{t-3}+\sqrt {1-a_ta_{t-1}a_{t-2}}\hat Z_{3}
Xt=atat−1at−2
Xt−3+1−atat−1at−2
Z^3 ——公式6
公式5我没有带大家一步步的计算了,只写出了最终结果,大家可以自己算一算,非常简单,也只用到了高斯分布的相关性质。注意上述的
Z
3
^
\hat {Z_3}
Z3^同样服从
N
(
0
,
1
)
N(0,1)
N(0,1)的高斯分布。那么公式6就得到了
x
t
x_t
xt时刻图像和
x
t
−
3
x_{t-3}
xt−3时刻图像的关系,我们如果这么一直计算下去,就会得到
x
t
x_t
xt时刻图像和
x
0
x_{0}
x0时刻图像的关系。但是这样的推导貌似很漫长,随着向后推导你会发现这种推导是有规律的。我们可以来比较一下公式4和公式6的结果,你会发现很明显的规律,这里我就根据这个规律直接写出
x
t
x_t
xt时刻图像和
x
0
x_{0}
x0时刻图像的关系,你看看和你想的是否一致喔,公式如下:
**X
t
=
a
ˉ
t
X
0
1
−
a
ˉ
t
Z
^
t
X_t=\sqrt {{{\bar a}_t}} X_0+\sqrt {1-\bar a_t}\hat Z_t
Xt=aˉt
X0+1−aˉt
Z^t** ——公式7
其中
a
ˉ
t
\bar a_t
aˉt表示累乘操作,即
a
ˉ
t
=
a
t
⋅
a
t
−
1
⋅
a
t
−
2
⋯
a
1
{{\bar a}_t} = {a_t} \cdot {a_{t - 1}} \cdot {a_{t - 2}} \cdots {a_1}
aˉt=at⋅at−1⋅at−2⋯a1 ,
Z
^
t
\hat Z_t
Z^t同样服从
N
(
0
,
1
)
N(0,1)
N(0,1)的高斯分布。【这里
Z
^
t
\hat Z_t
Z^t只是一个表示,只要
Z
Z
Z服从标准高斯分布即可,用什么表示都行】这个公式7就是整个正向过程的核心公式喔,**其表示
x
t
x_t
xt时刻的图像可以由
x
0
x_0
x0时刻的图像和一个标准高斯噪声表示**,大家需要牢记这个公式哦,在后文以及代码中会用到。🍈🍈🍈
逆向过程
逆向过程是将高斯噪声还原为预期图片的过程。先来看看我们已知条件有什么,其实就一个
x
t
x_t
xt时刻的高斯噪声。我们希望将
x
t
x_t
xt时刻的高斯噪声变成
x
0
x_0
x0时刻的图像,是很难一步到位的,因此我们思考能不能和正向过程一样,先考虑
x
t
x_t
xt时刻图像和
x
t
−
1
x_{t-1}
xt−1时刻的关系,然后一步步向前推导得出结论呢。好的,思路有了,那就先来想想如何由已知的
x
t
x_t
xt时刻图像得到
x
t
−
1
x_{t-1}
xt−1时刻图像叭。🥂🥂🥂
有没有大佬想出怎么办呢?我就不卖关子了,要想由
x
t
x_t
xt时刻图像得到
x
t
−
1
x_{t-1}
xt−1时刻图像,我们需要利用正向过程中的结论,我们在正向过程中可以由
x
t
−
1
x_{t-1}
xt−1时刻图像得到
x
t
x_{t}
xt时刻图像,然后利用贝叶斯公式即可求解。
!!!???什么,贝叶斯公式,不知道大家是否了解。如果不知道的建议去学习一下概率的知识,如果实在也不想学,大家就记住贝叶斯公式的表达式即可,如下:
那么我们将利用贝叶斯公式来求
x
t
−
1
x_{t-1}
xt−1时刻图像,公式如下:
q
(
X
t
−
1
∣
X
t
)
=
q
(
X
t
∣
X
t
−
1
)
q
(
X
t
−
1
)
q
(
X
t
)
q({X_{t - 1}}|{X_t}) = q({X_t}|{X_{t - 1}})\frac{{q({X_{t - 1}})}}{{q({X_t})}}
q(Xt−1∣Xt)=q(Xt∣Xt−1)q(Xt)q(Xt−1) ——公式8
公式8中
q
(
X
t
∣
X
t
−
1
)
q({X_t}|{X_{t - 1}})
q(Xt∣Xt−1)我们可以求得,就是刚刚正向过程求的嘛。🍟🍟🍟但
q
(
X
t
−
1
)
q(X_{t - 1})
q(Xt−1)和
q
(
X
t
)
q(X_{t})
q(Xt)是未知的。又由公式7可知,可由
X
0
X_0
X0得到每一时刻的图像,那当然可以得到
X
t
X_t
Xt和
X
t
−
1
X_{t-1}
Xt−1时刻的图像,故将公式8加一个
X
0
X_0
X0作为已知条件,将公式8变成公式9,如下:
q
(
X
t
−
1
∣
X
t
,
X
0
)
=
q
(
X
t
∣
X
t
−
1
,
X
0
)
q
(
X
t
−
1
∣
X
0
)
q
(
X
t
∣
X
0
)
q({X_{t - 1}}|{X_t},{X_0}) = q({X_t}|{X_{t - 1}},{X_0})\frac{{q({X_{t - 1}}|{X_0})}}{{q({X_t}|{X_0})}}
q(Xt−1∣Xt,X0)=q(Xt∣Xt−1,X0)q(Xt∣X0)q(Xt−1∣X0) ——公式9
现在可以发现公式9右边3项都是可以算的啦,我们列出它们的公式和对应的分布,如下图所示:
知道了公式9等式右边3项服从的分布,我们就可以计算出等式左边的
q
(
X
t
−
1
∣
X
t
,
X
0
)
q({X_{t - 1}}|{X_t},{X_0})
q(Xt−1∣Xt,X0)。大家知道怎么计算嘛,这个很简单啦,没有什么技巧,就是纯算。在附录->高斯分布性质部分我们知道了高斯分布的表达式为:
f
(
x
)
=
1
2
π
σ
e
−
(
x
−
u
)
2
2
σ
2
f(x) = \frac{1}{{\sqrt {2\pi \sigma } }}{e^{ - \frac{{{{(x - u)}^2}}}{{2{\sigma ^2}}}}}
f(x)=2πσ
1e−2σ2(x−u)2。那么我们只需要求出公式9等式右边3个高斯分布表达式,然后进行乘除运算即可求得
q
(
X
t
−
1
∣
X
t
,
X
0
)
q({X_{t - 1}}|{X_t},{X_0})
q(Xt−1∣Xt,X0)。
上图为等式右边三个高斯分布表达式,这个结果怎么得的大家应该都知道叭,就是把各自的均值和方差代入高斯分布表达式即可。现我们只需对上述三个式子进行对应乘除运算即可,如下图所示:
好了,我们上图中得到了式子
M
⋅
e
−
1
2
[
(
α
t
β
t
1
1
−
a
ˉ
t
−
1
)
X
t
−
1
2
−
(
2
a
ˉ
t
β
t
X
t
2
a
ˉ
t
−
1
1
−
a
ˉ
t
−
1
X
0
)
X
t
−
1
C
(
X
t
,
X
0
)
]
M \cdot {e^{ - \frac{1}{2}[(\frac{{{\alpha _t}}}{{{\beta _t}}} + \frac{1}{{1 - {{\bar a}_{t - 1}}}})X_{t - 1}^2 - (\frac{{2\sqrt {{{\bar a}_t}} }}{{{\beta _t}}}{X_t} + \frac{{2\sqrt {{{\bar a}_{t - 1}}} }}{{1 - {{\bar a}_{t - 1}}}}{X_0}){X_{t - 1}} + C({X_t},{X_0})]}}
M⋅e−21[(βtαt+1−aˉt−11)Xt−12−(βt2aˉt
Xt+1−aˉt−12aˉt−1
X0)Xt−1+C(Xt,X0)]其实就是
q
(
X
t
−
1
∣
X
t
)
q({X_{t - 1}}|{X_t})
q(Xt−1∣Xt)的表达式了。知道了这个表达式有什么用呢,主要是求出均值和方差。首先我们应该知道对高斯分布进行乘除运算的结果仍然是高斯分布,也就是说
q
(
X
t
−
1
∣
X
t
)
q({X_{t - 1}}|{X_t})
q(Xt−1∣Xt)服从高斯分布,那么他的表达式就为
f
(
x
)
=
1
2
π
σ
e
−
(
x
−
u
)
2
2
σ
2
=
1
2
π
σ
e
−
1
2
[
x
2
σ
2
−
2
u
x
σ
2
u
2
σ
2
]
f(x) = \frac{1}{{\sqrt {2\pi \sigma } }}{e^{ - \frac{{{{(x - u)}^2}}}{{2{\sigma ^2}}}}} = \frac{1}{{\sqrt {2\pi \sigma } }}{e^{ - \frac{1}{2}[\frac{{{x^2}}}{{{\sigma ^2}}} - \frac{{2ux}}{{{\sigma ^2}}} + \frac{{{u^2}}}{{{\sigma ^2}}}]}}
f(x)=2πσ
1e−2σ2(x−u)2=2πσ
1e−21[σ2x2−σ22ux+σ2u2],我们对比两个表达式,就可以计算出
u
u
u和
σ
2
\sigma^2
σ2,如下图所示:
现在我们有了均值
u
u
u和方差
σ
2
\sigma^2
σ2就可以求出
q
(
X
t
−
1
∣
X
t
)
q({X_{t - 1}}|{X_t})
q(Xt−1∣Xt)了,也就是求得了
x
t
−
1
x_{t-1}
xt−1时刻的图像。推导到这里不知道大家听懂了多少呢?其实你动动小手来算一算你会发现它还是很简单的。但是不知道大家有没有发现一个问题,我们刚刚求得的最终结果
u
u
u和
σ
2
\sigma^2
σ2中含义一个
X
0
X_0
X0,这个
X
0
X_0
X0是什么啊,他是我们最后想要的结果,现在怎么当成已知量了呢?这一块确实有点奇怪,我们先来看看我们从哪里引入了
X
0
X_0
X0。往上翻翻你会发现使用贝叶斯公式时我们利用了正向过程中推导的公式7来表示
q
(
X
t
−
1
)
q(X_{t - 1})
q(Xt−1)和
q
(
X
t
)
q(X_{t})
q(Xt),但是现在看来那个地方会引入一个新的未知量
X
0
X_0
X0,该怎么办呢?这时我们考虑用公式7来反向估计
X
0
X_0
X0,即反解公式7得出
X
0
X_0
X0的表达式,如下:
X
0
=
1
a
ˉ
t
(
X
t
−
1
−
a
ˉ
t
Z
^
t
)
{X_0} = \frac{1}{{\sqrt {{{\bar a}_t}} }}({X_t} - \sqrt {1 - {{\bar a}_t}} {{\hat Z}_t})
X0=aˉt
1(Xt−1−aˉt
Z^t) ——公式10
得到
X
0
X_0
X0的估计值,此时将公式10代入到上图的
u
u
u中,计算后得到最后估计的
u
~
{\tilde u}
u~,表达式如下:
u
~
=
1
a
t
(
x
t
−
β
t
1
−
a
ˉ
t
Z
^
t
)
\tilde u = \frac{1}{{\sqrt {{a_t}} }}({x_t} - \frac{{{\beta _t}}}{{\sqrt {1 - {{\bar a}_t}} }}{{\hat Z}_t})
u~=at
1(xt−1−aˉt
βtZ^t) ——公式11
好了,现在在整理一下
t
−
1
t-1
t−1时刻图像的均值
u
u
u和方差
σ
2
\sigma^2
σ2,如下图所示:
有了公式12我们就可以估计出
X
t
−
1
X_{t-1}
Xt−1时刻的图像了,接着就可以一步步求出
X
t
−
2
X_{t-2}
Xt−2、
X
t
−
3
X_{t-3}
Xt−3、
X
1
X_1
X1、
X
0
X_0
X0的图像啦。🍄🍄🍄🍄
原理小结
这一小节原理详解部分就为大家介绍到这里了,大家听懂了多少呢。相信你阅读了此部分后,对Diffusion Model的原理其实已经有了哥大概的解了,但是肯定还有一些疑惑的地方,不用担心,代码部分会进一步帮助大家。🌸🌸🌸
Diffusion Model源码解析✨✨✨
代码下载及使用
本次代码下载地址:Diffusion Model代码🚀🚀🚀
先来说说代码的使用吧,代码其实包含两个项目,一个的ddpm.py
,另一个是ddpm_condition.py
。大家可以理解为ddpm.py
是最简单的扩散模型,ddpm_condition.py
是ddpm.py
的优化。本节会以ddpm.py
为大家讲解。代码使用起来非常简单,首先在ddpm.py
文件中指定数据集路径,即设置dataset_path
的值,然后我们就可以运行代码了。需要注意的是,如果你使用的是CPU的话,那么你可能还需要修改一下代码中的device
参数,这个就很简单啦,大家自己摸索摸索就能研究明白。
这里来简单说说ddpm
的意思,英文全称为Denoising Diffusion Probabilistic Model
,中文译为去噪扩散概率模型
。🍄🍄🍄
代码流程图
这里我们直接来看论文中给的流程图好了,如下:
看到这个图你大概率是懵逼的,我来稍稍为大家解释一下。首先这个图表示整个算法的流程分为了训练阶段(Training)和采样阶段(Sampling)。
- Training
我们先来看看训练阶段我们做了什么?众所周知,训练我们需要有真实值和预测值,那么对于本例的真实值和预测值是什么呢?真实值是我们输入的图片,预测值是我们输出的图片吗?其实不是,这里我就不和大家卖关子了。对于本例来说,真实值和预测值都是噪声,我们同样拿下图为大家做个示范。
我们在正向过程中加入的噪声其实都是已知的,是可以作为真实值的。而逆向过程相当于一个去噪过程,我们用一个模型来预测噪声,让正向过程每一步加入的噪声和逆向过程对应步骤预测的噪声尽可能一致,而逆向过程预测噪声的方式就是丢入模型训练,其实就是Training中的第五步。
- Sampling
知道了训练过程,采样过程就很简单了,其实采样过程就对应我们理论部分介绍的逆向过程,由一个高斯噪声一步步向前迭代,最终得到
X
0
X_0
X0时刻图像。
代码解析
首先,按照我们理论部分应该有一个正向过程,其最重要的就是最后得出的公式7,如下:
**X
t
=
a
ˉ
t
X
0
1
−
a
ˉ
t
Z
^
t
X_t=\sqrt {{{\bar a}_t}} X_0+\sqrt {1-\bar a_t}\hat Z_t
Xt=aˉt
X0+1−aˉt
Z^t**
那么我们在代码中看一看是如何利用这个公式7的,代码如下:
def noise\_images(self, x, t):
sqrt_alpha_hat = torch.sqrt(self.alpha_hat[t])[:, None, None, None]
sqrt_one_minus_alpha_hat = torch.sqrt(1 - self.alpha_hat[t])[:, None, None, None]
Ɛ = torch.randn_like(x)
return sqrt_alpha_hat \* x + sqrt_one_minus_alpha_hat \* Ɛ, Ɛ
Ɛ为随机的标准高斯分布,其实也就是真实值。大家可以看出,上式的返回值sqrt_alpha_hat * x + sqrt_one_minus_alpha_hat
其实就表示公式7。【注:这个代码我省略了很多细节,我只把关键的代码展示给大家看,要想完全明白,还需要大家记住调试调试了】
接着我们就通过一个模型预测噪声,如下:
predicted_noise = model(x_t, t)
model
的结构很简单,就是一个Unet结构,然后里面嵌套了几个Transformer机制,我就不带大家跳进去慢慢看了。现在有了预测值,也有了真实值Ɛ【返回后Ɛ用noise表示】,就可以计算他们的损失并不断迭代了。
loss = mse(noise, predicted_noise)
optimizer.zero_grad()
loss.backward()
optimizer.step()
上述其实就是训练过程的大体结构,我省略了很多,要是大家有任何问题的话可以评论区留言讨论。现在就来看看采样过程的代码吧!!!
def sample(self, model, n):
logging.info(f"Sampling {n} new images....")
model.eval()
with torch.no_grad():
x = torch.randn((n, 3, self.img_size, self.img_size)).to(self.device)
# for i in tqdm(reversed(range(1, self.noise\_steps)), position=0):
for i in tqdm(reversed(range(1, 5)), position=0):
t = (torch.ones(n) \* i).long().to(self.device)
predicted_noise = model(x, t)
alpha = self.alpha[t][:, None, None, None]
alpha_hat = self.alpha_hat[t][:, None, None, None]
beta = self.beta[t][:, None, None, None]
if i > 1:
noise = torch.randn_like(x)
else:
noise = torch.zeros_like(x)
x = 1 / torch.sqrt(alpha) \* (x - ((1 - alpha) / (torch.sqrt(1 - alpha_hat))) \* predicted_noise) + torch.sqrt(beta) \* noise
model.train()
x = (x.clamp(-1, 1) + 1) / 2
x = (x \* 255).type(torch.uint8)
return x
上述代码关键的就是 x = 1 / torch.sqrt(alpha) * (x - ((1 - alpha) / (torch.sqrt(1 - alpha_hat))) * predicted_noise) + torch.sqrt(beta) * noise
这个公式,其对应着代码流程图中Sampling阶段中的第4步。需要注意一下这里的跟方差
σ
t
\sigma_t
σt这个公式给的是
β
\sqrt {\beta}
β
,但其实在我们理论计算时为
β
t
(
1
−
a
ˉ
t
−
1
)
1
−
a
ˉ
t
\sqrt {\frac{{{\beta _t}(1 - {{\bar a}_{t - 1}})}}{{1 - {{\bar a}_t}}}}
1−aˉtβt(1−aˉt−1)
,这里做了近似处理计算,即
a
ˉ
t
−
1
{\bar a}_{t - 1}
aˉt−1和
a
ˉ
t
\bar a_t
aˉt都是非常小且近似0的数,故把
(
1
−
a
ˉ
t
−
1
)
1
−
a
ˉ
t
{\frac{{(1 - {{\bar a}_{t - 1}})}}{{1 - {{\bar a}_t}}}}
1−aˉt(1−aˉt−1)当成1计算,这里注意一下就好。🍵🍵🍵
代码小结
可以看出,这一部分我所用的篇幅很少,只列出了关键的部分,很多细节需要大家自己感悟。比如代码中时刻T的用法,其实是较难理解的,代码中将其作为正余弦位置编码处理。如果你对位置编码不熟悉,可以看一下我的这篇文章的附录部分,有详细的介绍位置编码,相信你读后会有所收获。🌿🌿🌿
参考链接
附录
高斯分布性质
高斯分布又称正态分布,其表达式为:
f
(
x
)
=
1
2
π
σ
e
−
(
x
−
u
)
2
2
σ
2
f(x) = \frac{1}{{\sqrt {2\pi \sigma } }}{e^{ - \frac{{{{(x - u)}^2}}}{{2{\sigma ^2}}}}}
f(x)=2πσ
1e−2σ2(x−u)2
其中
u
u
u为均值,
σ
2
\sigma^2
σ2为方差。若随机变量服X从正态均值为
u
u
u,方差为
σ
2
\sigma^2
σ2的高斯分布,一般记为
X
∼
N
(
u
,
σ
2
)
X \sim N(u,{\sigma ^2})
X∼N(u,σ2)。此外,有一点大家需要知道,如果我们知道一个随机变量服从高斯分布,且知道他们的均值和方差,那么我们就能写出该随机变量的表达式。
高斯分布还有一些非常好的性质,现举一些例子帮助大家理解。
- 若
X
∼
N
(
u
,
σ
2
)
X \sim N(u,\sigma^2)
X∼N(u,σ2),则
a
X
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上物联网嵌入式知识点,真正体系化!
由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、电子书籍、讲解视频,并且后续会持续更新
需要这些体系化资料的朋友,可以加我V获取:vip1024c (备注嵌入式)
) * i).long().to(self.device)
predicted_noise = model(x, t)
alpha = self.alpha[t][:, None, None, None]
alpha_hat = self.alpha_hat[t][:, None, None, None]
beta = self.beta[t][:, None, None, None]
if i > 1:
noise = torch.randn_like(x)
else:
noise = torch.zeros_like(x)
x = 1 / torch.sqrt(alpha) * (x - ((1 - alpha) / (torch.sqrt(1 - alpha_hat))) * predicted_noise) + torch.sqrt(beta) * noise
model.train()
x = (x.clamp(-1, 1) + 1) / 2
x = (x * 255).type(torch.uint8)
return x
上述代码关键的就是 `x = 1 / torch.sqrt(alpha) * (x - ((1 - alpha) / (torch.sqrt(1 - alpha_hat))) * predicted_noise) + torch.sqrt(beta) * noise`这个公式,其对应着代码流程图中Sampling阶段中的第4步。需要注意一下这里的跟方差
σ
t
\sigma\_t
σt这个公式给的是
β
\sqrt {\beta}
β
,但其实在我们理论计算时为
β
t
(
1
−
a
ˉ
t
−
1
)
1
−
a
ˉ
t
\sqrt {\frac{{{\beta \_t}(1 - {{\bar a}\_{t - 1}})}}{{1 - {{\bar a}\_t}}}}
1−aˉtβt(1−aˉt−1)
,这里做了近似处理计算,即
a
ˉ
t
−
1
{\bar a}\_{t - 1}
aˉt−1和
a
ˉ
t
\bar a\_t
aˉt都是非常小且近似0的数,故把
(
1
−
a
ˉ
t
−
1
)
1
−
a
ˉ
t
{\frac{{(1 - {{\bar a}\_{t - 1}})}}{{1 - {{\bar a}\_t}}}}
1−aˉt(1−aˉt−1)当成1计算,这里注意一下就好。🍵🍵🍵
#### 代码小结
可以看出,这一部分我所用的篇幅很少,只列出了关键的部分,很多细节需要大家自己感悟。比如代码中时刻T的用法,其实是较难理解的,代码中将其作为正余弦位置编码处理。如果你对位置编码不熟悉,可以看一下我的[这篇文章](https://bbs.csdn.net/topics/618679757)的附录部分,有详细的介绍位置编码,相信你读后会有所收获。🌿🌿🌿
### 参考链接
>
> [由浅入深了解Diffusion](https://bbs.csdn.net/topics/618679757)🍁🍁🍁
>
>
>
### 附录
#### 高斯分布性质
高斯分布又称正态分布,其表达式为:
f
(
x
)
=
1
2
π
σ
e
−
(
x
−
u
)
2
2
σ
2
f(x) = \frac{1}{{\sqrt {2\pi \sigma } }}{e^{ - \frac{{{{(x - u)}^2}}}{{2{\sigma ^2}}}}}
f(x)=2πσ
1e−2σ2(x−u)2
其中
u
u
u为均值,
σ
2
\sigma^2
σ2为方差。若随机变量服X从正态均值为
u
u
u,方差为
σ
2
\sigma^2
σ2的高斯分布,一般记为
X
∼
N
(
u
,
σ
2
)
X \sim N(u,{\sigma ^2})
X∼N(u,σ2)。此外,有一点大家需要知道,如果我们知道一个随机变量服从高斯分布,且知道他们的均值和方差,那么我们就能写出该随机变量的表达式。
---
高斯分布还有一些非常好的性质,现举一些例子帮助大家理解。
* 若
X
∼
N
(
u
,
σ
2
)
X \sim N(u,\sigma^2)
X∼N(u,σ2),则
a
X
[外链图片转存中...(img-9Z3dc9Sf-1715881160313)]
[外链图片转存中...(img-nhwSzai5-1715881160314)]
**既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上物联网嵌入式知识点,真正体系化!**
**由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、电子书籍、讲解视频,并且后续会持续更新**
**需要这些体系化资料的朋友,可以加我V获取:vip1024c (备注嵌入式)**
**[如果你需要这些资料,可以戳这里获取](https://bbs.csdn.net/topics/618679757)**