1.病毒传播系统进化树绘制与分析
2.Matplotlib-plt.scatter( )绘制散点图
3.python测试集的个数多少合适
4.[转]Megatron-LM源码系列(八): Context Parallel并行
5.遇见神器!cufflinks:一款美不胜收的 Python 可视化工具包!
6.利用Python爬虫爬取淘宝商品做数据挖掘分析实战篇,超详细教程
病毒传播系统进化树绘制与分析
病毒传播系统的进化树绘制与分析技术有助于深入理解疾病传播模式和演变路径。通过研究埃博拉病毒等流行病,科学家们利用一系列工具如numpy的网页js获取源码轴功能以及数据处理方法来构建和解析这些树状结构。
imp.load_source()函数在Python中扮演着关键角色,它将外部源代码文件导入模块,这对于处理病毒传播数据的动态加载至关重要。例如,假设在E:/Code/Python3/目录下的test.py文件,演示了如何有效地应用这些技术来管理数据处理。
isinstance()函数则是判断对象类型的重要工具,与type()不同,它在比较类型一致性时更为常用。这个函数的语法简单,通过比较对象类型与给定的classinfo,返回True或False,这对于病毒传播模型中的对象类型验证至关重要。
在可视化方面,matplotlib库提供了如plt.scatter()和plt.axvspan()、plt.axhspan()等功能,帮助我们理解病毒传播的时空分布和可能的隔离区域。DATE_FORMAT()函数则确保日期格式的准确性,这对于追踪疫情的时间线至关重要。
最后,path_effects属性在贝塞尔曲线(Bezier曲线)的绘制中,为文本和线条提供了额外的效果,这在构建病毒传播路径的可视化图示时,能够提升信息的清晰度和易读性。
Matplotlib-plt.scatter( )绘制散点图
英文源码详解
参考链接颜色
参考函数使用链接
1)基本参数讲解
其中使用plt.colorbar显示颜色的数值映射
参数详解:
使用参数c为不同的点赋予不同的颜色值,我们将与数据长度一致的颜色列表传入c中。
参数cmap
我们还要问这种渐变颜色选择色系,即cmap参数
‘Perceptually Uniform Sequential’
‘Sequential’
‘Sequential2’
Diverging
Qualitative
Miscellaneous
python测试集的个数多少合适
导读:今天首席CTO笔记来给各位分享关于python测试集的个数多少合适的相关内容,如果能碰巧解决你现在面临的问题,别忘了关注本站,现在开始吧!划分训练、测试集和数据观察一般在进行模型的测试时,我们会将数据分为训练集和测试集。在给定的样本空间中,拿出大部分样本作为训练集来训练模型,剩余的小部分样本使用刚建立的模型进行预测。
train_test_split函数利用伪随机数生成器将数据集打乱。默认情况下0.为训练集,0.测试集。
在构建机器学习模型之前,通常最好检查一下数据,看看如果不用机器学习能不能轻松完成任务,或者需要的信息有没有包含在数据中。
此外,检查数据也是发现异常值和特殊值的好方法。举个例子,可能有些鸢尾花的测量单位是英寸而不是厘米。在现实世界中,经常会遇到不一致的数据和意料之外的测量数据。检查数据的最佳方法之一就是将其可视化。一种可视化方法是绘制散点图(scatterplot)。数据散点图将一个特征作为x轴,另一个特征作为y轴,将每一个数据点绘制为图上的一个点。不幸的是,计算机屏幕只有两个维度,所以我们一次只能绘制两个特征(也可能是3个)。用这种方法难以对多于3个特征的数据集作图。解决这个问题的一种方法是绘制散点图矩阵(pairplot),从而可以两两查看所有的特征。如果特征数不多的话,比如我们这里有4个,这种方法是很合理的。但是你应该记住,散点图矩阵无法同时显示所有特征之间的关系,所以这种可视化方法可能无法展示数据的某些有趣内容。
数据点的颜色与鸢尾花的品种相对应。为了绘制这张图,我们首先将NumPy数组转换成pandasDataFrame。pandas有一个绘制散点图矩阵的函数,叫作scatter_matrix。矩阵的对角线是每个特征的直方图
从图中可以看出,利用花瓣和花萼的测量数据基本可以将三个类别区分开。这说明机器学习模型很可能可以学会区分它们。
参考资料:
Python机器学习基础教程
Pandas官方文档
如何利用python将txt文件划分训练集和测试集“按照8:2的比例对项目分出训练集和测试集”:从数据源中随机抽取%的数据作为“训练集”,其余的是“测试集”
import?random
with?open("datasource.txt",?'rt')?as?handle:
dataset?=?[map(int,?ln.split())?for?ln?in?handle]
#?乱序
random.shuffle(dataset)
#?[训练集,?测试集]
pos?=?len(dataset)?*.8
parts?=?dataset[:pos],?dataset[pos:]
训练集测试集8比2合适吗不合适。
数据量较小(1w条以下),一般的源码螺旋攻略划分是,训练集:验证集:测试集=8:1:1(有的地方说是6:2:2),训练集:测试集=2:1至4:1(总之测试集不要超过%)。训练集:训练参数,此处的参数是指普通参数,即在神经网络中能够被梯度下降算法所更新的,如权值。验证集:用于调超参数,监控模型是否发生过拟合,能够被多次使用,进行人工调参。此处的超参数,如神经网络中的网络层数、网络节点数、迭代次数、学习率测试集:评估最终模型泛化能力,被一次使用。
BP神经网络的训练集需要大样本吗?一般样本个数为多少?BP神经网络的训练集需要大样本吗?一般样本个数为多少?
BP神经网络样本数有什么影响
学习神经网络这段时间,有一个疑问,BP神经网络中训练的次数指的网络的迭代次数,如果有a个样本,每个样本训练次数n,则网络一共迭代an次,在na情况下,网络在不停的调整权值,减小误差,跟样本数似乎关系不大。而且,a大了的话训练时间必然会变长。
换一种说法,将你的数据集看成一个固定值,那么样本集与测试集也可以按照某种规格确定下来如7:3所以如何看待样本集的多少与训练结果呢?或者说怎么使你的网络更加稳定,更加符合你的所需。
我尝试从之前的一个例子中看下区别
如何用行Java代码实现深度神经网络算法
作者其实是实现了一个BP神经网络,不多说,看最后的例子
一个运用神经网络的例子
最后我们找个简单例子来看看神经网络神奇的效果。为了方便观察数据分布,我们选用一个二维坐标的数据,下面共有4个数据,方块代表数据的类型为1,三角代表数据的类型为0,可以看到属于方块类型的数据有(1,2)和(2,1),属于三角类型的数据有(1,1),(2,2),现在问题是需要在平面上将4个数据分成1和0两类,并以此来预测新的数据的类型。
描述
我们可以运用逻辑回归算法来解决上面的分类问题,但是逻辑回归得到一个线性的直线做为分界线,可以看到上面的红线无论怎么摆放,总是有一个样本被错误地划分到不同类型中,所以对于上面的数据,仅仅一条直线不能很正确地划分他们的分类,如果我们运用神经网络算法,可以得到下图的分类效果,相当于多条直线求并集来划分空间,这样准确性更高。
描述
简单粗暴,用作者的代码运行后训练次。根据训练结果来预测一条新数据的分类(3,1)
预测值(3,1)的结果跟(1,2)(2,1)属于一类属于正方形
这时如果我们去掉2个样本,则样本输入变成如下
//设置样本数据,对应上面的4个二维坐标数据
double[][]data=newdouble[][]{ { 1,2},{ 2,2}};
//设置目标数据,对应4个坐标数据的分类
double[][]target=newdouble[][]{ { 1,0},{ 0,1}};
1
2
3
4
1
2
3
4
则(3,1)结果变成了三角形,
如果你选前两个点你会发现直接一条中间线就可以区分这时候的你的结果跟之前4个点时有区别so你得增加样本直到这些样本按照你所想要的方式分类,所以样本的多少重要性体现在,样本得能反映所有的特征值(也就是输入值),样本多少或者特征(本例子指点的位置特征)决定的你的网络的训练结果,!!!这是我们反推出来的结果。这里距离深度学习好像近了一步。
另外,这个行代码的神经网络没有保存你训练的网络,所以你每次运行都是重新训练的网络。其实,在你训练过后权值已经确定了下来,我们确定网络也就是根据权值,so只要把训练后的权值保存下来,将需要分类的数据按照这种权值带入网络,即可得到输出值,也就是网页源码方格一旦网络确定,权值也就确定,一个输入对应一个固定的输出,不会再次改变!个人见解。
最后附上作者的源码,作者的文章见开头链接
下面的实现程序BpDeep.java可以直接拿去使用,
importjava.util.Random;
publicclassBpDeep{
publicdouble[][]layer;//神经网络各层节点
publicdouble[][]layerErr;//神经网络各节点误差
publicdouble[][][]layer_weight;//各层节点权重
publicdouble[][][]layer_weight_delta;//各层节点权重动量
publicdoublemobp;//动量系数
publicdoublerate;//学习系数
publicBpDeep(int[]layernum,doublerate,doublemobp){
this.mobp=mobp;
this.rate=rate;
layer=newdouble[layernum.length][];
layerErr=newdouble[layernum.length][];
layer_weight=newdouble[layernum.length][][];
layer_weight_delta=newdouble[layernum.length][][];
Randomrandom=newRandom();
for(intl=0;llayernum.length;l++){
layer[l]=newdouble[layernum[l]];
layerErr[l]=newdouble[layernum[l]];
if(l+1layernum.length){
layer_weight[l]=newdouble[layernum[l]+1][layernum[l+1]];
layer_weight_delta[l]=newdouble[layernum[l]+1][layernum[l+1]];
for(intj=0;jlayernum[l]+1;j++)
for(inti=0;ilayernum[l+1];i++)
layer_weight[l][j][i]=random.nextDouble();//随机初始化权重
}
}
}
//逐层向前计算输出
publicdouble[]computeOut(double[]in){
for(intl=1;llayer.length;l++){
for(intj=0;jlayer[l].length;j++){
doublez=layer_weight[l-1][layer[l-1].length][j];
for(inti=0;ilayer[l-1].length;i++){
layer[l-1][i]=l==1?in[i]:layer[l-1][i];
z+=layer_weight[l-1][i][j]*layer[l-1][i];
}
layer[l][j]=1/(1+Math.exp(-z));
}
}
returnlayer[layer.length-1];
}
//逐层反向计算误差并修改权重
publicvoidupdateWeight(double[]tar){
intl=layer.length-1;
for(intj=0;jlayerErr[l].length;j++)
layerErr[l][j]=layer[l][j]*(1-layer[l][j])*(tar[j]-layer[l][j]);
while(l--0){
for(intj=0;jlayerErr[l].length;j++){
doublez=0.0;
for(inti=0;ilayerErr[l+1].length;i++){
z=z+l0?layerErr[l+1][i]*layer_weight[l][j][i]:0;
layer_weight_delta[l][j][i]=mobp*layer_weight_delta[l][j][i]+rate*layerErr[l+1][i]*layer[l][j];//隐含层动量调整
layer_weight[l][j][i]+=layer_weight_delta[l][j][i];//隐含层权重调整
if(j==layerErr[l].length-1){
layer_weight_delta[l][j+1][i]=mobp*layer_weight_delta[l][j+1][i]+rate*layerErr[l+1][i];//截距动量调整
layer_weight[l][j+1][i]+=layer_weight_delta[l][j+1][i];//截距权重调整
}
}
layerErr[l][j]=z*layer[l][j]*(1-layer[l][j]);//记录误差
}
}
}
publicvoidtrain(double[]in,double[]tar){
double[]out=computeOut(in);
updateWeight(tar);
}
}
1
2
3
4
5
6
7
8
9
1
2
3
4
5
6
7
8
9
下面是这个测试程序BpDeepTest.java的源码:
importjava.util.Arrays;
publicclassBpDeepTest{
publicstaticvoidmain(String[]args){
//初始化神经网络的基本配置
//第一个参数是一个整型数组,表示神经网络的层数和每层节点数,比如{ 3,,,,,2}表示输入层是3个节点,输出层是2个节点,中间有4层隐含层,每层个节点
//第二个参数是学习步长,第三个参数是动量系数
BpDeepbp=newBpDeep(newint[]{ 2,,2},0.,0.8);
//设置样本数据,对应上面的4个二维坐标数据
double[][]data=newdouble[][]{ { 1,2},{ 2,2},{ 1,1},{ 2,1}};
//设置目标数据,对应4个坐标数据的分类
double[][]target=newdouble[][]{ { 1,0},{ 0,1},{ 0,1},{ 1,0}};
//迭代训练次
for(intn=0;n;n++)
for(inti=0;idata.length;i++)
bp.train(data[i],target[i]);
//根据训练结果来检验样本数据
for(intj=0;jdata.length;j++){
double[]result=bp.computeOut(data[j]);
System.out.println(Arrays.toString(data[j])+":"+Arrays.toString(result));
}
//根据训练结果来预测一条新数据的分类
double[]x=newdouble[]{ 3,1};
double[]result=bp.computeOut(x);
System.out.println(Arrays.toString(x)+":"+Arrays.toString(result));
}
}
python随机森林分类模型,测试集和训练集的样本数没有准确按照%和%分配?
进行比例划分的时候从int型转化为了float型,float型总是会有微小的误差的,这个不是大问题。
比如你输入1-0.9,可能返回0.1,也可能返回0.或者0.,这是计算机存储机制导致的。
结语:以上就是首席CTO笔记为大家整理的关于python测试集的个数多少合适的全部内容了,感谢您花时间阅读本站内容,希望对您有所帮助,更多关于python测试集的个数多少合适的相关内容别忘了在本站进行查找喔。
[转]Megatron-LM源码系列(八): Context Parallel并行
原文链接: Megatron-LM源码系列(八): Context Parallel并行
Context Parallel并行(CP)与sequence并行(SP)相比,核心差异在于SP只针对Layernorm和Dropout输出的activation在sequence维度进行切分,而CP则进一步扩展,对所有input输入和所有输出activation在sequence维度上进行切分,形成更高效的并行处理策略。除了Attention模块外,其他如Layernorm、Dropout等模块在CP并行中无需任何修改,因为它们在处理过程中没有涉及多token间的交互。
Attention模块之所以特殊,是因为在计算过程中,每个token的查询(query)需要与同一sequence中其他token的键(key)和值(value)进行交互计算,存在内在依赖性。因此,在进行CP并行时,计算开始前需要通过allgather通信手段获取所有token的KV向量,反向计算时则通过reduce_scatter分发gradient梯度。
为了降低显存使用,前向计算阶段每个GPU仅保存部分KV块,反向阶段则通过allgather通信获取全部KV数据。这些通信操作在特定的rank位置(相同TP组内)进行,底层通过send和recv等操作实现allgather和reduce_scatter。
以TP2-CP2的transformer网络为例,CP并行的通信操作在Attention之前执行,其他则为TP通信。AG表示allgather,RS表示reduce_scatter,AG/RS表示前向allgather反向reduce_scatter,RS/AG表示前向reduce_scatter反向allgather。
TP2对应为[GPU0, GPU1], [GPU2, GPU3],CP2指的就是TP组相同位置的rank号,即[GPU0, GPU2], [GPU1, GPU3]。CP并行类似于Ring Attention,但提供了OSS与FlashAttention版本,并去除了冗余的low-triangle causal masking计算。
LLM常因序列长度过长而导致显存耗尽(OOM)。传统解决方法包括重计算或扩大TP(tensor parallel)大小,但各自存在计算代价增加或线性fc计算时间减少与通信难以掩盖的问题。CP则能更高效地解决这一问题,每个GPU处理一部分序列,同时减少CP倍的通信和计算量,同时保持TP不变,使得activation量也减少CP倍。性能优化结果展示于图表中,用户可通过指定--context-parallel-size在Megatron中实现CP。
具体源码实现以Megatron-Core 0.5.0版本为例进行说明。
参考资料:
遇见神器!cufflinks:一款美不胜收的 Python 可视化工具包!
遇见神器!cufflinks:一款美不胜收的 Python 可视化工具包!
近几年以来,Python 可视化库丰富多样,应用广泛。cufflinks 库作为新秀,以其简单易用、图形美观、代码量小的特色脱颖而出。只需一两行代码,docker源码仓库就能生成精美的图表。以下是使用方法和示例。
1.用法简单
cufflinks 主要与 dataFrame 数据结合使用,绘图函数是 dataFrame.iplot。记住这个函数即可。iplot 函数参数丰富,如 kind、title、xTitle、yTitle等。
2.少量代码画出漂亮图形
cufflinks 提供多种主题样式,包括 polar、pearl、henanigans、solar、ggplot、space 和 white。折线图、散点图、气泡图、子图、箱形图、直方图和 3D 图等均可轻松生成。
3.丰富的绘图功能
cufflinks 库功能丰富,更多细节和学习资源请访问 Github 链接:github.com/santosjorge/...
以下是部分图表示例代码:
折线图代码:df.iplot(kind='lines')
散点图代码:df.iplot(kind='scatter')
气泡图代码:df.iplot(kind='bubble')
子图代码:df.iplot(kind='subplots')
箱形图代码:df.iplot(kind='box')
直方图代码:df.iplot(kind='hist')
3D图代码:df.iplot(kind='3d')
交流群
加入 Python 学习交流群,微信:dkl。加群时请备注:方向+学校/公司+知乎。
文章推荐
1.妙不可言!Mito:一款超级棒的 JupyterLab 扩展程序!
2.微软出品!FLAML:一款可以自动化机器学习过程的神器!
3.机器学习模型应该如何调优?这里有三大改进策略
4.又在放大招!这个 Github 项目针对 Python 初学者!
5.刷分神器,使用 Hyperopt 实现 Lightgbm 自动化调参!
6.这张 Python 数据科学速查表真棒!
7.PySnooper:永远不要使用 print 进行调试
8.超越 Facebook 的 Prophet,NeuralProphet 这个时序工具包也太强了!
9.干货!张最新可视化大屏模板,各行业数据直接套用(含源码)
.用 Python 写出这样的进度条,刷新了我对进度条的认知!
.Rich:Python开发者的完美终端工具!
.超级干货!史上最全数据分析学习路线(附资源下载)
整理不易,有所收获,点个赞和爱心❤️,更多精彩欢迎关注。
利用Python爬虫爬取淘宝商品做数据挖掘分析实战篇,超详细教程
项目内容
案例选择商品类目:沙发;数量:共页个商品;筛选条件:天猫、销量从高到低、价格元以上。
以下是分析,源码点击文末链接
项目目的
1. 对商品标题进行文本分析,词云可视化。
2. 不同关键词word对应的sales统计分析。
3. 商品的价格分布情况分析。
4. 商品的销量分布情况分析。
5. 不同价格区间的商品的平均销量分布。
6. 商品价格对销量的影响分析。
7. 商品价格对销售额的影响分析。
8. 不同省份或城市的商品数量分布。
9. 不同省份的商品平均销量分布。
注:本项目仅以以上几项分析为例。
项目步骤
1. 数据采集:Python爬取淘宝网商品数据。
2. 数据清洗和处理。
3. 文本分析:jieba分词、wordcloud可视化。
4. 数据柱形图可视化barh。
5. 数据直方图可视化hist。
6. 数据散点图可视化scatter。
7. 数据回归分析可视化regplot。
工具&模块:
工具:本案例代码编辑工具Anaconda的Spyder。
模块:requests、retrying、missingno、jieba、matplotlib、wordcloud、imread、seaborn等。
原代码和相关文档后台回复“淘宝”下载。
一、爬取数据
因淘宝网是saml编程源码反爬虫的,虽然使用多线程、修改headers参数,但仍然不能保证每次%爬取,所以,我增加了循环爬取,直至所有页爬取成功停止。
说明:淘宝商品页为JSON格式,这里使用正则表达式进行解析。
代码如下:
二、数据清洗、处理:
(此步骤也可以在Excel中完成,再读入数据)
代码如下:
说明:根据需求,本案例中只取了item_loc、raw_title、view_price、view_sales这4列数据,主要对标题、区域、价格、销量进行分析。
代码如下:
三、数据挖掘与分析:
1. 对raw_title列标题进行文本分析:
使用结巴分词器,安装模块pip install jieba。
对title_s(list of list格式)中的每个list的元素(str)进行过滤,剔除不需要的词语,即把停用词表stopwords中有的词语都剔除掉:
为了准确性,这里对过滤后的数据title_clean中的每个list的元素进行去重,即每个标题被分割后的词语唯一。
观察word_count表中的词语,发现jieba默认的词典无法满足需求。
有的词语(如可拆洗、不可拆洗等)却被cut,这里根据需求对词典加入新词(也可以直接在词典dict.txt里面增删,然后载入修改过的dict.txt)。
词云可视化:
安装模块wordcloud。
方法1:pip install wordcloud。
方法2:下载Packages安装:pip install 软件包名称。
软件包下载地址:lfd.uci.edu/~gohlke/pyt...
注意:要把下载的软件包放在Python安装路径下。
代码如下:
分析
1. 组合、整装商品占比很高;
2. 从沙发材质看:布艺沙发占比很高,比皮艺沙发多;
3. 从沙发风格看:简约风格最多,北欧风次之,其他风格排名依次是美式、中式、日式、法式等;
4. 从户型看:小户型占比最高、大小户型次之,大户型最少。
2. 不同关键词word对应的sales之和的统计分析:
(说明:例如词语‘简约’,则统计商品标题中含有‘简约’一词的商品的销量之和,即求出具有‘简约’风格的商品销量之和)
代码如下:
对表df_word_sum中的word和w_s_sum两列数据进行可视化。
(本例中取销量排名前的词语进行绘图)
由图表可知:
1. 组合商品销量最高;
2. 从品类看:布艺沙发销量很高,远超过皮艺沙发;
3. 从户型看:小户型沙发销量最高,大小户型次之,大户型销量最少;
4. 从风格看:简约风销量最高,北欧风次之,其他依次是中式、美式、日式等;
5. 可拆洗、转角类沙发销量可观,也是颇受消费者青睐的。
3. 商品的价格分布情况分析:
分析发现,有一些值太大,为了使可视化效果更加直观,这里我们选择价格小于的商品。
代码如下:
由图表可知:
1. 商品数量随着价格总体呈现下降阶梯形势,价格越高,在售的商品越少;
2. 低价位商品居多,价格在-之间的商品最多,-之间的次之,价格1万以上的商品较少;
3. 价格1万元以上的商品,在售商品数量差异不大。
4. 商品的销量分布情况分析:
同样,为了使可视化效果更加直观,这里我们选择销量大于的商品。
代码如下:
由图表及数据可知:
1. 销量以上的商品仅占3.4%,其中销量-之间的商品最多,-之间的次之;
2. 销量-之间,商品的数量随着销量呈现下降趋势,且趋势陡峭,低销量商品居多;
3. 销量以上的商品很少。
5. 不同价格区间的商品的平均销量分布:
代码如下:
由图表可知:
1. 价格在-之间的商品平均销量最高,-之间的次之,元以上的最低;
2. 总体呈现先增后减的趋势,但最高峰处于相对低价位阶段;
3. 说明广大消费者对购买沙发的需求更多处于低价位阶段,在元以上价位越高平均销量基本是越少。
6. 商品价格对销量的影响分析:
同上,为了使可视化效果更加直观,这里我们选择价格小于的商品。
代码如下:
由图表可知:
1. 总体趋势:随着商品价格增多其销量减少,商品价格对其销量影响很大;
2. 价格-之间的少数商品销量冲的很高,价格-之间的商品多数销量偏低,少数相对较高,但价格以上的商品销量均很低,没有销量突出的商品。
7. 商品价格对销售额的影响分析:
代码如下:
由图表可知:
1. 总体趋势:由线性回归拟合线可以看出,商品销售额随着价格增长呈现上升趋势;
2. 多数商品的价格偏低,销售额也偏低;
3. 价格在0-的商品只有少数销售额较高,价格2万-6万的商品只有3个销售额较高,价格6-万的商品有1个销售额很高,而且是最大值。
8. 不同省份的商品数量分布:
代码如下:
由图表可知:
1. 广东的最多,上海次之,江苏第三,尤其是广东的数量远超过江苏、浙江、上海等地,说明在沙发这个子类目,广东的店铺占主导地位;
2. 江浙沪等地的数量差异不大,基本相当。
9. 不同省份的商品平均销量分布:
代码如下:
热力型地图
源码:Python爬取淘宝商品数据挖掘分析实战
小白看过来,新人如何入门嵌入式
作为一个新人,怎样学习嵌入式Linux
原文链接:网页链接
作为一个新人,怎样学习嵌入式Linux?被问过太多次,特写这篇文章来回答一下。
在学习嵌入式Linux之前,肯定要有C语言基础。汇编基础有没有无所谓(就那么几条汇编指令,用到了一看就会)。C语言要学到什么程度呢?越熟当然越好,不熟的话也要具备基本技能。比如写一个数组排序、输入数字求和什么的。学C语言唯一的方法是多写程序多练习,编译出错没关系,自己去解决;执行出错没关系,自己去分析。以前我是用VC来练习C语言的,经常去尝试着写一些C语言竞赛的题目。它们是纯C、纯数学、纯逻辑的题目,不涉及界面这些东西,很适合煅炼你的编程能力。
回到主题,首先我们要明白你的目的是什么,大概来说所谓嵌入式Linux可以分为两部分:底层系统、应用开发。如果你是想做应用开发,那么你去把C语言、数据结构、JAVA什么的学好吧。嵌入式应用开发和PC上的应用开发并没有什么特别要注意的。也许你说在嵌入式上要做些优化,是的,要优化,但是未经优化的程序和PC上的程序开发没什么差别。另外,当你有能力去优化时,你已经不用来问这个问题了。具体到某个例子,比如说开发界面,在PC上我们用VC;在嵌入式Linux里也许我们用QT也许用Android,这个时候你应该去学学QT、Android的编程。但是基础还是C或JAVA,在此基础上去熟悉它们的接口。你学过VC的话,也是要花时间去了解那些类、控件的。
如果你的目的是想学习底层系统,这是我的专长,倒是可以说一点。在回答这个问题之前,我先回答:不少人问我,到底是学驱动还是学应用?
我只能说凭兴趣,并且驱动和应用并不是截然分开的
我们说的驱动,其实并不局限于硬件的操作,还有操作系统的原理、进程的休眠唤醒调度等概念。 想写出一个好的应用,想比较好的解决应用碰到的问题,这些知识你应该懂
做应用门槛低,特别是现在的ANDROID,纯JAVA。做应用的发展路径个人认为就是业务纯熟。比如在通信行业、IPTV行业、手机行业,你了解行业的需求。所以,当领导的人,多是做应用的。
做驱动,其实我不想称为“做驱动”,而是想称为“做底层系统”,做好了这是通杀各行业。我工作几年,做过手机、IPTV、会议电视,但是这些产品对我毫无差别,因为我只做底层。他们的业务跟我没关系。当应用出现问题,他们解决不了时,我就会从内核角度给他们出主意,给他们提供工具。 做底层的发展方向,个人认为是技术专家。
其实,做底层还是做应用,之间并没有一个界线,有底层经验,再去做应用,你会感觉很踏实。有了业务经验,你再了解一下底层,很快就可以组成一个团队。
回到怎么学的问题上。嵌入式Linux底层系统包含哪些东西?不要急,举一个例子你就知道了。
电脑一开机,那些界面是谁显示的?是BIOS,它做什么?一些自检,然后从硬盘上读入windows,并启动它。类似的,这个BIOS对应于嵌入式Linux里的bootloader。这个bootloader要去Flash上读入Linux内核,并启动它。
启动windows的目的是什么?当然是上网聊天什么的了。这些上网、聊天工具在哪?
在C盘、D盘上。所以, windows要先识别出C盘、D盘。在Linux下我们称为根文件系统。
windows能识别出C盘、D盘,那么肯定能读写硬盘才行。这涉及的东西称为驱动程序。当然不仅仅是硬盘,还有网卡、USB等等。嵌入式Linux能从Flash上读出并执行应用程序,肯定也得有Flash的驱动程序啊,当然也不仅仅是Flash。
先说到这里吧,嵌入式LINUX里含有bootloader, 内核, 驱动程序、根文件系统这4大块。
一、bootloader:
它就是一个稍微复杂的裸板程序。但是要把这裸板程序看懂写好一点都不容易。Windows下好用的工具弱化了我们的编程能力。
很多人一玩嵌入式就用ADS、KEIL。你能回答这几个问题吗?
1. 一上电,CPU从哪里取指令执行?
答:一般从Flash上指令。
2. 但是Flash一般是只能读不能直接写的,如果我用到全局变量,这些全局变量在哪里?
答:全局变量应该在内存里
3. 那么谁把全局变量放到内存里去?
答:长期用ADS、KEIL的朋友,你能回答吗?这需要"重定位"。在ADS或KEIL里,重定位的代码是制作这些工具的公司帮你写好了。你可曾去阅读过?
4. 内存那么大,我怎么知道把"原来存在Flash上的内容"读到内存的"哪个地址去"?
答:这个地址用"链接脚本"决定,在ADS里有scatter文件,KEIL里也有类似的文件。但是,你去研究过吗?
5. 你说重定位是把程序从Flash复制到内存,那么这个程序可以读Flash啊?
答:是的,要能操作Flash。当然不仅仅是这些,还有设置时钟让系统运行得更快等等。
自问自答到这里吧,bootloader这一个裸板程序,其实有3部分要点:
对硬件的操作
对ARM体系处理器的了解
程序的基本概念:重定位、栈、代码段数据段BSS段什么的。
对硬件的操作,需要看原理图、芯片手册。这需要一定的硬件知识,不求你能设计硬件,但是至少能看懂; 不求能看懂模拟电路,但是要能看懂数字电路。这方面的能力我是在学校里学到的,微机原理、数字电路这2本书(书名忘了)就足够了。但是我怀疑你有无耐心把这2本书看完。我不知道现在有没有更快捷的书。想速成的话,就先放掉这块吧,不懂就问GOOGLE、发贴。
另外,芯片手册是肯定要读的,别去找中文的,就看英文的。开始是非常痛苦,以后就会发现那些语法、词汇一旦熟悉后,读任何芯片手册都很容易。对ARM体系处理器的了解, 看杜春蕾的<ARM体系架构与编程>吧,里面讲有汇编指令,有异常模式、MMU等。也就这3块内容需要你了解。
程序的基本概念,王道当然是去看编译原理了。可惜,这类书绝对是天书级别的。劝你若非超级天才还是别去看了。就看我写的<嵌入式Linux应用开发完全手册>和第1期视频吧,别担心,不用花钱。照着视频把硬件相关的实验做了,这些概念就清楚了。我还没有
发现第2套讲这些概念的书或视频。
对于bootloader,我学习时是先看了<ARM体系架构与编程>,然后自己写程序把各个硬件的实验都做了一遍,比如GPIO、时钟、SDRAM、UART、NAND。把它们都弄清楚了,组台在一起就很容易看懂u-boot了
总结一下,看懂硬件原理图、看芯片手册,这需要你自己去找资料。剩下的,就按<嵌入式Linux应用开发完全手册>和第1期视频的章节目录去学习吧。
二、内核:
想速成的人,先跨过内核的学习,直接学习怎么写驱动。
想成为高手,内核必须深刻了解。注意,我说的是了解,我没奢望去写出一个内核。
要对里面的调度机制、内存管理机制、文件管理机制等等有所了解。
推荐两本书:
1. 通读<linux内核完全注释>,请看薄的那本(浮燥的社会讲求速度, 呵),
2. 选读<Linux内核情景分析>, 想了解哪一块就读哪一节
三、驱动:
驱动包含两部分:硬件本身的操作、驱动程序的框架。
又是硬件,还是要看得懂原理图、读得懂芯片手册,多练吧。
说到驱动框架,有一些书介绍一下。LDD3,即<Linux设备驱动>,老外写的那本,里面介绍了不少概念,值得一读。但是,它的作用也就限于介绍概念了。我基本上是入门之前用它来熟悉一下概念,入门后就扔掉了。
驱动方面比较全的介绍,应该是宋宝华的<linux设备驱动开发详解>了,老实说我只看过目录,有不少人说好,这里推荐一下。要想深入了解某一块,<Linux内核情景分析>绝对是超5星级推荐。你别指望把它读完,多页,上下两册呢。我是某一块不清楚时,就去翻一下它。任何一部分,这书都可以讲上2、3百页,非常详细。并且是以某个目标来带你分析内核源码。它以linux 2.4为例,但是原理相通,同样适用于其它版本的linux。
还有没有其他介绍?呵呵,当然有了,韦东山Linux视频第2期。<嵌入式Linux应用开发完全手册>里对驱动讲得不多,不够深入。于是我录制了这期视频。不仅仅教你怎么写怎么改驱动,还教你为什么这样写这样改驱动。
每一个驱动都是现场编写:
用绘图板画图讲解──相当于学校里老师在黑板上画图讲解,很直观绝对不是对着PPT念。
用source insight当场写程序,从第1行开始写,每一课都是这样。我讲了多个驱动,就写了多个程序。
写完就编译、测试。
很全面,字符设备驱动、块设备、网卡驱动3大类齐全,硬件介绍、驱动框架分析、测试3大类齐全。
培训机构里教的内容,远不及这期视频丰富。我在多个培训机构讲过课,从没看到哪个老师敢每一课都当场讲解当场编写代码,当场测试,除我之外!也没看到哪个培训机构讲完这些内容──因为时间不够,讲完起码要一个月,但是这部分基本只有2周授课时间。
把你手上的开发板所涉及的硬件,都去尝试写一个驱动吧。有问题就先"痛苦地思考",思考的过程中你会把很多不相关的知识串联起来,最终贯通。
四、根文件系统:
大家有没有想过这2个问题:
1. 对于Linux做出来的产品,有些用作监控、有些做手机、有些做平板。那么内核启动后,挂载根文件系统后,应该启动哪一个应用程序呢?
答:内核不知道也不管应该启动哪一个用户程序。它只启动init这一个应用程序,它对应/sbin/init。显然,这个应用程序就要读取配置文件,根据配置文件去启动用户程序(监控、手册界面、平板界面等等)这个问题提示我们,文件系统的内容是有一些约定的,比如要有/sbin/init,要有配置文件
2. 你写的hello,world程序,有没有想过里面用到的printf是谁实现的?
答:这个函数不是你实现的,是库函数实现的。它运行时,得找到库。这个问题提示我们,文件系统里还要有库。
简单的自问自答到这里,要想深入了解,可以看一下busybox的init.c,就可以知道init进程做的事情了。当然,也可以看<嵌入式Linux应用开发完全手册>里构建根文件系统那章。
说一下我的学习经历吧。
我在学校时读的是物理电子专业,其实课程里没有教怎么设计电路,只是教了些电子电路方面的知识。PCB的设计是在实验室里自学的,只设计过2层板,现在忘记得差不多了。但是保留了看原理图、看芯片手册的能力。
选修了软件学位,对软件设计挺感兴趣,但是也只是学了C语言、数据库而已。凭着兴趣做了不少竞赛题。没能力去参加竞赛,但是把C语言练得很扎实。
在实验室、在第1家公司,就是设计些简单的PCI卡,写一下windows的驱动程序
在第2家公司,用单片机做车载电话,开始走上纯软件的道路。
开始感到单片机的不足,辞职半年闭门学Linux,从red hat怎么操作开始。步骤就是先看<ARM体系架构与编程>,再自己写裸板程序操作硬件,接着到分析u-boot。同时看<linux内核完全注释>,对LINUX框架有所了解。在写裸板时,建议各位加强对中断的理解,内核就是用中断来完成各种功能的。
分析完u-boot,就开始进行简单的驱动编程了,这时候,能力还很弱。
开始去中兴上班,工作2年,编写各类驱动、解决各类问题(驱动问题、帮助定位应用问题),能力得到煅炼。
总结一下:
1. 硬件方面的书: 微机原理、数字电路,高校里的教材。毕业多年,忘名了。
2. Linux方面的书:
<ARM体系架构与编程>
<嵌入式Linux应用开发完全手册>
<Linux设备驱动>,老外写的那本
<linux设备驱动开发详解>
<linux内核完全注释>
<Linux内核情景分析>
3. 视频:
韦东山Linux视频第1期(基于S3C录制): ARM实验,u-boot,文件系统,初级驱动
韦东山Linux视频第1期(基于S3C录制): 裸板程序
韦东山Linux视频第2期: 高级驱动
韦东山Linux视频第3期:项目实战
韦东山Linux视频第4期:Android驱动
视频信息请看网页链接
————————————————
版权声明:本文为博主「韦东山」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:/thisway_diy/article/details/