【cs230】吴恩达Deep Learning-2/3
【cs230】吴恩达Deep Learning-2/3
- 0. 课程计划
- 5. AI + Healthcare
- 5.1 AI可以解决哪些高影响力问题
- 5.1.1 Levels
- 5.1.2 学习范式的变化
- 5.2 实际项目举例--医学影像
- 5.2.1 1D-ECG
- 5.2.2 2D-Chest X-Ray
- 5.2.3 模型的解释
- 5.2.3 3D-MR Scans
- 5.3 细胞分割
- 6. DL项目策略
- 7. 解释NN
- 7.1 解释NN的输出
- 7.1.1 saliency maps
- 7.1.2 occlusion sensitivity
- 7.1.3 class activation maps
- 7.2 可视化NN
- 7.2.1 gradient ascent
- 7.2.2 dataset search
- 7.2.3 deconvolution
- 7.3 Deep Dream
0. 课程计划
课程地址
2018video地址
2020slide地址
吴恩达书籍Machine Learning Yearning地址
本系列相关链接:
【cs229】吴恩达Machine Learning-1/2
【cs230】吴恩达Deep Learning-1/3
5. AI + Healthcare
5.1 AI可以解决哪些高影响力问题
5.1.1 Levels
5.1.2 学习范式的变化
Machine Learning: 输入+特征工程+网络=输出
Deep Learning: 输入+NN(兼具特征提取功能)=输出
AI+healthcare:输入+工程师设计NN=输出
未来AI+healthcare:输入+自动设计NN(不再需要AI工程师)=输出
人们常问,AI工程师会取代影像医生吗?其实,AI工程师可能更快被取代,很有趣!
5.2 实际项目举例–医学影像
5.2.1 1D-ECG
检测心律不齐;
ECG在心脏附近皮肤贴多个电极,显示心脏一段时间的电活动;有时检测时间不够;
挑战:
- ECG测试一般来说都是贴12组电极,从多个维度理解心跳;但是实验中只用了1个电极;
心跳是3D的,12个不同位置的电极可以从多个角度透视; - 心律之间的差异非常微妙;
开发经验:
- 看书或者请教,获得领域知识(人类如何诊断,最热门最常用的处理方法)
方法[1]中(ResNet变种),需要人类专家给每段数据指定标签;
https://stanfordmlgroup.github.io/projects/ecg/
[1] P. Rajpurkar, A. Y. Hannun, M. Haghpanahi, C. Bourn, and A. Y. Ng, “Cardiologist-level arrhythmia detection with convolutional neural networks,” arXiv preprint arXiv:1707.01836, 2017.
https://github.com/awni/ecg
[2] A. Y. Hannun et al., “Cardiologist-level arrhythmia detection and classification in ambulatory electrocardiograms using a deep neural network,” Nature medicine, vol. 25, no. 1, pp. 65-69, 2019.
5.2.2 2D-Chest X-Ray
胸片–>CheXNet(DenseNet变种)–>分类结果
肺炎不致命,没有病理的金标准;因此评估方法为:以其他专家的诊断为标准,计算每个专家的F1-score。
5.2.3 模型的解释
class activation maps
Learning deep features for discriminative localization zhou et al. (2016)
概率热图,可以告诉医生模型对疾病诊断的解释,将最终的疾病的诊断权力交还给医生。
下面是一个在线读X片工程,可以检测14中病理,可以看到概率,也可以看到热图:
https://xray4all.com/
5.2.3 3D-MR Scans
膝盖的MRI,可用于识别膝盖的多种疾病,这不是一个多分类问题, 而是一个多标签问题。或者说,同一个人的膝盖可能同时存在多种问题。
医学模型训练后,需要用外部数据做验证 External Validation。
医生的诊断水平,在模型的辅助中、和辅助后,能提高吗?是提高了,还是过于依赖模型而降低了?
5.3 细胞分割
目标:将显微镜下的细胞做分割;
数据:医生在A\B\C三种显微镜下有5w、2.5w、2.5w图像,最终希望用于C;
Q1. 数据切分:训练集、验证集、测试集
- 90:5:5,而不是60:20:20,因为数据量足够大;
- 验证集和测试集的数据分布必须一样,因此都只含有C的图;
Q2. 数据增强:
裁剪、加噪声、改变对比度、翻转、旋转、缩放…
但是注意,数据增强应当合理(例如OCR中不应该翻转),有些情况的数据增强是无用的、甚至伤害性的。
Q3. 迁移学习:
假设你获得了一个训练良好的模型M2,你想迁移成M1以解决自己的问题,那么,这涉及到哪些超参?
- L–你从M2中取前L层;
- L0–你在L个M2层后面新加L0层;
- Lf–在训练M1时,冻结前Lf层,Lf≤LL_f\leq LLf≤L;
Q4. 边界权重:
如果用户希望边界更清晰/更明显,怎么做?
- 标签不在是0/1,而是0/1/2,表示不是细胞、是细胞、是边界;
- 重新设计损失函数,L=∑αLnocell+βLcell+LboundaryL=\sum \alpha L_{no~cell}+\beta L_{cell}+L_{boundary}L=∑αLno cell+βLcell+Lboundary,尝试不同的系数(不是学习、而是训练技巧);
Q5. 假设你为医生做了一个分类器,用于分类图中是否有癌症细胞。你怎么解释到底是哪个细胞起得作用?
- ∂y/∂x\partial y/\partial x∂y/∂x
- 可视化权重不行,因为权重与input无关;
Q6. 医生的诊断能力是95%,网络的诊断能力是98%,这可能吗?
如果标签都是同一个医生诊断的,那么这不应该;
如果标签是一群医生诊断的,那么这ok,表示医生的平均水平/最高水平高于某一个医生;
Q7. 你设计了一个自动驾驶软件,将输入图片传给行人识别模块、车辆识别模块,两者的输出再送给决策模块。但是,现在输出的决策不对,如何确定是哪个模块的错?
- 控制变量法,看前提正确的情况下,单个模块是否正确;
- 如果单个模块都ok,但是整体输出出错,那么,考虑新增模块,因为你的建模可能没有覆盖所有信息,例如路面标志等。
6. DL项目策略
吴恩达从CEO角度,给出做项目的建议。
- 读paper,看blog,下开源project,看不懂联系作者
- 收集少量数据,打标签
仍然以触发词的语音识别项目为例,测试样本是10s语音,触发词说完的那个时间点标签为1,其他标签为0.
Q1. 如果训练集准确率95%, 但是测试集总是输出0(没有检测到触发词),怎么办?
如果加入很棒的团队工作5年,获得经验,那当然非常棒,但也花费了太多时间;
吴恩达建议,在课程中通过一个小时的引导,让学员快速积累经验;
A1. 因为数据非常不平衡,所以准确率不足以表示你真正关心的性能。
- 更改评价方式
例如给正样本更高的权重; - 使验证集的数据更加平衡
resample - 用连续多个1表示出现触发词
对应实际问题,这样做意味着触发词出现后的0.5s打开灯都是可以接受的。
DL工作流类似debug,解决一个问题,出现一个新问题,继续。
Q2. 通过误差分析,你发现overfitting了,怎么办?
- 减小特征数
- 正则化
- 数据增强
此例中,增加背景音,或者增加假的触发词,可以防止网络 “背题”。
Q3. 下列哪种收集背景音的方式更快?
- 打开麦克风,在校园里乱转
- 从网上下载
- 悬赏任务(例如,amazon mechanical turk)
吴恩达的建议:
- ok,快,且质量可控
- 渠道未必好找,质量不可控,时间不可控
- 其次,毕竟花时间,可能一周
所以,如何收集数据,可以组内头脑风暴,然后评估耗时和可行性。
总体建议:不要觉得只节省了一点点时间,想想每件事缩短了几倍。
7. 解释NN
一个非常实用的pytorch可视化工程:
https://github.com/utkuozbulak/pytorch-cnn-visualizations
7.1 解释NN的输出
7.1.1 saliency maps
[1] K. Simonyan, A. Vedaldi, and A. Zisserman, “Deep inside convolutional networks: Visualising image classification models and saliency maps,” arXiv preprint arXiv:1312.6034, 2013.
注意:sdog(x)s_{dog}(x)sdog(x)指的是这张图在softmax的前一层的输出,而不是0.85这个数。因为0.85是dog的得分除以总得分,如果使这个数变大,也可能是通过使总分变小,那就不等价了。
有趣的是,可以根据贡献大的点,分割出这只狗!
优势:快,但不准;
7.1.2 occlusion sensitivity
以小方块遮挡原图,移动遮挡的位置,重新推理当前图的score。
[2] M. D. Zeiler and R. Fergus, “Visualizing and understanding convolutional networks,” in European conference on computer vision, 2014: Springer, pp. 818-833.
7.1.3 class activation maps
这里的激活图与7.1.1的显著图不同。
之所以叫”类激活图“,是因为这个解释中使用到了不同类的www来参与解释,例如下图用的是dog类,如果问你human的激活图,那么公式中需要替换为human类的www。
[3] Zhou, B., et al. Learning deep features for discriminative localization. in Proceedings of the IEEE conference on computer vision and pattern recognition. 2016.
将编码层保留,将最后的Flatten层替换成Global Average Pooling (GAP),继续训练新增的几层。
知道了最后一个卷积层的特征值,知道了每个channel对结局的贡献,则加权可得每个位置的贡献,再resize到原图大小。
缺点:需要微调。
7.2 可视化NN
此处指的是图像网络/cnn的可视化,非图像网络(例如语音、文字…)使用注意力机制。
7.1小节向用户解释了网络输出的关注点在哪,但没有解释在网络看来,什么是狗。
7.2.1 gradient ascent
也叫“class model visualization”,目标是最大化L,使狗的得分最高。
缺点:需要额外训练;
7.2.2 dataset search
将大量数据集送入网络,观察哪些图使得某个channel特征图最能被激活,也就意味着这个channel编码的正是这几个图的相同点。
注意,这里送入网络的不是原图,而是原图的crop后的一块,为什么?因为高层的一个点的感受野是局部。
缺点:耗时;
7.2.3 deconvolution
反卷积层/上采样层背后的动机:将浓缩的编码信息展开,增大height和width。
用法:分割网络的蒙板、自动编码器的解码、GAN的生成器、反向重建weight
为了可视化某个中间层的某个channel对应到图像空间的意义,可以如下:
置0
这个操作的目的是使得这一channel的意义更加集中,去掉一些杂乱的、不那么重要的细节。UNPOOL
池化是不可逆的,根据池化后的结果无法反推输入数据;
因此,我们要做的就是反推出一个近似答案。
一种直观的做法是,直接将最大值广播,但是这个太粗糙;
另一个近似的方法是,多记录一个开关,根据开关把最大值所在index反射回去。
这种近似合理吗?合理,因为那些被置0的点,在正向传播时本来就没有参与计算,也不影响loss。
Relu
Relu的反向与Poll的思路类似,也需要额外记录开关,因为原来小于0的点也没有参与计算,因此不需要更新权重。
UnRelu与Relu的反向不同,因为UnRelu我们关注的是哪个特征对输出有正面影响。
DeConv
- 1D conv
input:8×18\times18×1, pad =2
weight: 1 channel, stride = 2, filter_size = 4
output: 5×1×1,ny=nx−f+2ps+15\times1\times1,n_y=\frac{n_x-f+2p}{s}+15×1×1,ny=snx−f+2p+1
Y5×1=W5×12X12×1⇓假设W可逆X12×1=W12×5−1Y5×1⇓假设W是正交矩阵,WTW=IX12×1=W12×5TY5×1(如果非正交甚至非可逆,仍然这么用,因为逆的计算太慢)⇓裁剪掉X中被pad的上下各2行X8×1=W8×5TY5×1[y1y2y3y4y5]=[w1w2w3w40000000000w1w2w3w40000000000w1w2w3w40000000000w1w2w3w40000000000w1w2w3w4][00x1x2x3x4x5x6x7x800][00‾x1x2x3x4x5x6x7x8‾00]=[w10000w2‾0‾0‾0‾0‾w3w1000w4w20000w3w1000w4w20000w3w1000w4w20000w3w10‾0‾0‾w4‾w2‾0000w30000w4][y1y2y3y4y5]⇓sub−pixelconvolution[00‾x1x2x3x4x5x6x7x8‾00]=[w4w3w2w1000000000000‾w4‾w3‾w2‾w1‾0‾0‾0‾0‾0‾0‾0‾0‾0‾0‾00w4w3w2w1000000000000w4w3w2w1000000000000w4w3w2w1000000000000w4w3w2w1000000000000w4w3w2w1000000000000w4w3w2w1000000000000w4w3w2w10000‾0‾0‾0‾0‾0‾0‾0‾0‾w4‾w3‾w2‾w1‾0‾0‾0000000000w4w3w2w1000000000000w4w3w2w1][000y10y20y30y40y5000]\begin{aligned} Y_{5\times1}&=W_{5\times12}X_{12\times1}\\ &\dArr假设W可逆\\ X_{12\times1}&=W^{-1}_{12\times5}Y_{5\times1}\\ &\dArr假设W是正交矩阵,W^TW=I\\ X_{12\times1}&=W^{T}_{12\times5}Y_{5\times1}(如果非正交甚至非可逆,仍然这么用,因为逆的计算太慢)\\ &\dArr裁剪掉X中被pad的上下各2行\\ X_{8\times1}&=W^{T}_{8\times5}Y_{5\times1}\\ \begin{bmatrix} y_1 \\ y_2 \\ y_3 \\ y_4 \\ y_5 \\ \end{bmatrix}&=\begin{bmatrix} w_1&w_2&w_3&w_4&0&0&0&0&0&0&0&0 \\ 0&0&w_1&w_2&w_3&w_4&0&0&0&0&0&0 \\ 0&0&0&0&w_1&w_2&w_3&w_4&0&0&0&0 \\ 0&0&0&0&0&0&w_1&w_2&w_3&w_4&0&0 \\ 0&0&0&0&0&0&0&0&w_1&w_2&w_3&w_4 \\ \end{bmatrix}\begin{bmatrix} 0 \\ 0 \\ x_1 \\ x_2 \\ x_3 \\ x_4 \\ x_5 \\ x_6 \\ x_7 \\ x_8 \\ 0 \\ 0 \\ \end{bmatrix}\\ \begin{bmatrix} 0 \\ \underline{0} \\ x_1 \\ x_2 \\ x_3 \\ x_4 \\ x_5 \\ x_6 \\ x_7 \\ \underline{x_8} \\ 0 \\ 0 \\ \end{bmatrix}&=\begin{bmatrix} w_1&0&0&0&0 \\ \underline{w_2}&\underline{0}&\underline{0}&\underline{0}&\underline{0} \\ w_3&w_1&0&0&0 \\ w_4&w_2&0&0&0 \\ 0&w_3&w_1&0&0 \\ 0&w_4&w_2&0&0 \\ 0&0&w_3&w_1&0 \\ 0&0&w_4&w_2&0 \\ 0&0&0&w_3&w_1 \\ \underline{0}&\underline{0}&\underline{0}&\underline{w_4}&\underline{w_2} \\ 0&0&0&0&w_3 \\ 0&0&0&0&w_4 \\ \end{bmatrix}\begin{bmatrix} y_1 \\ y_2 \\ y_3 \\ y_4 \\ y_5 \\ \end{bmatrix}\\ &\dArr sub-pixel~convolution\\ \begin{bmatrix} 0 \\ \underline{0} \\ x_1 \\ x_2 \\ x_3 \\ x_4 \\ x_5 \\ x_6 \\ x_7 \\ \underline{x_8} \\ 0 \\ 0 \\ \end{bmatrix}&=\begin{bmatrix} w_4&w_3&w_2&w1&0&0&0&0&0&0&0&0&0&0&0 \\ \underline{0}&\underline{w_4}&\underline{w_3}&\underline{w_2}&\underline{w1}&\underline{0}&\underline{0}&\underline{0}&\underline{0}&\underline{0}&\underline{0}&\underline{0}&\underline{0}&\underline{0}&\underline{0} \\ 0&0&w_4&w_3&w_2&w1&0&0&0&0&0&0&0&0&0 \\ 0&0&0&w_4&w_3&w_2&w1&0&0&0&0&0&0&0&0 \\ 0&0&0&0&w_4&w_3&w_2&w1&0&0&0&0&0&0&0 \\ 0&0&0&0&0&w_4&w_3&w_2&w1&0&0&0&0&0&0 \\ 0&0&0&0&0&0&w_4&w_3&w_2&w1&0&0&0&0&0 \\ 0&0&0&0&0&0&0&w_4&w_3&w_2&w1&0&0&0&0 \\ 0&0&0&0&0&0&0&0&w_4&w_3&w_2&w1&0&0&0 \\ \underline{0}&\underline{0}&\underline{0}&\underline{0}&\underline{0}&\underline{0}&\underline{0}&\underline{0}&\underline{0}&\underline{w_4}&\underline{w_3}&\underline{w_2}&\underline{w1}&\underline{0}&\underline{0} \\ 0&0&0&0&0&0&0&0&0&0&w_4&w_3&w_2&w1&0 \\ 0&0&0&0&0&0&0&0&0&0&0&w_4&w_3&w_2&w1 \\ \end{bmatrix}\begin{bmatrix} 0 \\ 0 \\ 0 \\ y_1 \\ 0 \\ y_2 \\ 0 \\ y_3 \\ 0 \\ y_4 \\ 0 \\ y_5 \\ 0 \\ 0 \\ 0 \\ \end{bmatrix} \end{aligned}Y5×1X12×1X12×1X8×1⎣⎢⎢⎢⎢⎡y1y2y3y4y5⎦⎥⎥⎥⎥⎤⎣⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎡00x1x2x3x4x5x6x7x800⎦⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎤⎣⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎡00x1x2x3x4x5x6x7x800⎦⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎤=W5×12X12×1⇓假设W可逆=W12×5−1Y5×1⇓假设W是正交矩阵,WTW=I=W12×5TY5×1(如果非正交甚至非可逆,仍然这么用,因为逆的计算太慢)⇓裁剪掉X中被pad的上下各2行=W8×5TY5×1=⎣⎢⎢⎢⎢⎡w10000w20000w3w1000w4w20000w3w1000w4w20000w3w1000w4w20000w3w1000w4w20000w30000w4⎦⎥⎥⎥⎥⎤⎣⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎡00x1x2x3x4x5x6x7x800⎦⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎤=⎣⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎡w1w2w3w40000000000w1w2w3w40000000000w1w2w3w40000000000w1w2w3w40000000000w1w2w3w4⎦⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎤⎣⎢⎢⎢⎢⎡y1y2y3y4y5⎦⎥⎥⎥⎥⎤⇓sub−pixel convolution=⎣⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎡w400000000000w3w40000000000w2w3w4000000000w1w2w3w4000000000w1w2w3w4000000000w1w2w3w4000000000w1w2w3w4000000000w1w2w3w4000000000w1w2w3w4000000000w1w2w3w4000000000w1w2w3w4000000000w1w2w3w4000000000w1w2w30000000000w1w200000000000w1⎦⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎤⎣⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎡000y10y20y30y40y5000⎦⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎤
最后两个反卷积的数学含义完全相同,但计算矩阵不同,目的是高效计算deconv:
A. 权重的顺序翻转了;
B. 新y前后补0,中间间隔0;
C. 新w的stride是1了;
- 2D deconv
上面我们从1d conv推导出1d deconv,并理解了1d decov可以用sub-pixel的形式等效计算。
x---->forword—>y, conv
x<–backword<–y, deconv
推广到2d deconv,y 4×44\times44×4,先写成sub-pixel形式y 9×99\times99×9,再与flip后的w做卷积,得到重建的x 6×66\times66×6;
观察这个过程,一个有趣的特性是,x的绿色部分,只有w的绿色部分参与过计算;
因此,一次deconv可以拆解成4个毫不相干的普通卷积,再将4次的结果按位置拼接起来。而stride=1的卷积非常高效!
[4] J. Yosinski, J. Clune, A. Nguyen, T. Fuchs, and H. Lipson, “Understanding neural networks through deep visualization,” arXiv preprint arXiv:1506.06579, 2015.
这篇论文发布了一个AlexNet权重可视化的在线工具, 对应的youtube视频, “shine light into the black-boxes”.
7.3 Deep Dream
与7.2.1梯度上升法类似,但谷歌的DeepDream团队做的更极端。
https://ai.googleblog.com/2015/06/inceptionism-going-deeper-into-neural.html
本章小节:
【cs230】吴恩达Deep Learning-2/3相关推荐
- Andrew Ng(吴恩达) deep learning 课程 (coursera)
引言 前段时间 Andrew Ng(吴恩达)在 Coursera 开设了深度学习的课程,正如 Andrew 在 Coursera 上的机器学习课程一样,Andrew 总是面向零基础的工程师来授课,而不 ...
- python下的橡皮线_python下载吴恩达deep learning编程习题
在cousera上注册deep learning后,可下载课后习题. 1.进入编程环境后,单击左上角的file-open,进入文件管理模式 2. 点击红圈文件夹进入根目录 3. 在根目录处右上角new ...
- 吴恩达Deep learning笔记(一)
Welcome to Deep learning Specialization 介绍了深度学习目前的发展状况以及未来的前景 Introdcution to Deep Learning what'is ...
- Stanford CS230吴恩达Reading Research Papers学习笔记
目录 Stanford CS230吴恩达Reading Research Papers学习笔记 如何通过更有效地阅读研究论文,来接触新领域知识 如何有效地针对一篇论文进行阅读 论文的多次阅读法 阅读论 ...
- coursera—吴恩达Machine Learning笔记(1-3周)
Machine Learning 笔记 笔记主要按照进度记录上课主要内容和部分代码实现,因为我会看一阶段再进行整理,内容会有一定交叉.关于代码部分,一开始我是只为了做作业而写代码的,现在觉得不妨仔细看 ...
- 吴恩达ex3_吴恩达Machine Learning Ex3 python实现
1.Multi-class classification 使用Logistic regression和neural networks来识别手写数字识别(从0到9).在第一部分练习中使用Logistic ...
- 学习笔记—1:多元线性回归模型,吴恩达2022Machine Learning
CSDN话题挑战赛第2期 参赛话题:学习笔记 一.公式部分 线性模型:即两个变量之间是一次函数关系的模型预测,为一元线性回归模型:而当所选取的x为多元时(例如x为多元的情况:房屋价格要考虑,位置.面积 ...
- 吴恩达第三周逻辑回归
分类问题 我们尝试预测的是结果是否属于某一个类(例如正确或错误) 分类举例 判断一封电子邮件是否是垃圾邮件 判断一次金融交易是否是欺诈 判断一个肿瘤是恶性的还是良性的 考查二元分类问题 我们将因变量( ...
- 从六大概念总结吴恩达机器学习书籍:如何做好工程项目实践?
选自towardsdatascience 作者:Niklas Donges 机器之心编译 在 ML 工程实践中,很多时候都会走一些弯路,可能是模型选错了,也可能是某个超参数一直不正确.那么我们该如何根 ...
最新文章
- python pip全称_Python pip 安装与使用
- 自定义线程池-线程类和任务类代码实现
- tomcat相关实验
- 由PPPOE看Linux网络协议栈的实现
- 坦克大战-C语言-详注版
- Google十大真理带给中国网络公司的启示
- IE浏览器经典故障分析与实战解决方案
- linux+yum安装终端php,centos下yum搭建安装linux+apache+mysql+php环境教程
- 关于安装vs2015后, vs2013打开项目工程失败崩溃的问题!
- godot读写本地文件
- 合宙Air724UG二次开发(2):资料描述
- 微信小程序开发之组件view,scroll-view,swiper,text,rich-text,button,image,navigator
- Python超详细学员管理系统【面向对象实现】
- tftp刷路由器 linux,路由器TFTP配置的四个步骤
- STM32-(ADC,DMA,重映射)
- 批量提取html title,怎样批量提取网站的标题和链接呢?
- 科研——高效收集paper的途径
- 灯泡,PC 与 云
- vmware convert P2V 错误二三事
- C语言实现1到100简单猜数字游戏