-
Notifications
You must be signed in to change notification settings - Fork 100
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* why * Update mkdocs.yml * turbo fan control * Update why-use-python.md
- Loading branch information
Showing
10 changed files
with
343 additions
and
0 deletions.
There are no files selected for viewing
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
# 涡轮卡的使用技巧-风扇调速 | ||
|
||
# 问题背景 | ||
|
||
我们使用涡轮卡的时候,一旦上了负载,会得到飞机起飞的效果,噪声巨大,这在办公室不是很合适。 | ||
|
||
涡轮卡资料图: | ||
|
||
![](turbo-card-usage-tips-fan-speed-adjustment/image.png) | ||
|
||
# 解决方案 | ||
|
||
为了避免噪声过大,我们可以使用一个软件调整风扇温度曲线,它叫 MSIAfterburner,下载地址:[https://www.msi.com/Landing/afterburner/graphics-cards](https://www.msi.com/Landing/afterburner/graphics-cards) | ||
|
||
安装好之后,进入设置页面: | ||
|
||
![](turbo-card-usage-tips-fan-speed-adjustment/image-1.png) | ||
|
||
然后拉低曲线,比如80度时,原本风扇转速是100%,你可以改为50%: | ||
|
||
![](turbo-card-usage-tips-fan-speed-adjustment/image-2.png) | ||
|
||
# 效果 | ||
|
||
修改前: | ||
|
||
![](turbo-card-usage-tips-fan-speed-adjustment/image-3.png) | ||
|
||
修改后: | ||
|
||
![](turbo-card-usage-tips-fan-speed-adjustment/image-4.png) | ||
|
||
可以看到风扇转速从 98% 降低到了 51%,噪声降低了很多。虽然使用过程中如果到了 90 度可能会过热,导致显卡降频,但是平时开发的时候完全够用了。真要跑训练的话,还是要放在机房里才行。 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,306 @@ | ||
# 为什么我们要用 Python 语言 | ||
|
||
# 什么是Python语言 | ||
|
||
Python是一种高级、通用的编程语言,由Guido van Rossum于1989年底发起,并在1991年首次发布。Python的设计哲学强调代码的可读性和简洁的语法(尤其是使用空格缩进来区分代码块,而不是使用大括号或关键字)。这使得Python的代码容易理解和维护。 | ||
|
||
以下是 2024 年 4 月的编程语言排行榜,可以看到 Python 排名第一,是最流行的编程语言: | ||
|
||
![](why-use-python/image.png) | ||
|
||
数据来源:[https://www.tiobe.com/tiobe-index/](https://www.tiobe.com/tiobe-index/) | ||
|
||
# C++、C#、Python 有什么不同 | ||
|
||
|特性/语言|C++|C#|Python| | ||
|---|---|---|---| | ||
|类型|编译型语言|编译型语言(运行于.NET框架/.NET Core)|解释型语言| | ||
|性能|高性能,接近硬件层面|高性能,通过JIT编译器优化执行|性能相对较低,解释执行| | ||
|内存管理|手动内存管理(需处理new和delete)|自动垃圾回收(无需手动管理内存)|自动垃圾回收(无需手动管理内存)| | ||
|语法复杂度|复杂,提供多种编程范式|相对简洁,基于C++改进|简洁明了,易于学习| | ||
|跨平台|支持,需考虑平台相关性|原生支持跨平台(.NET Core)|原生支持跨平台| | ||
|错误处理|支持异常处理,也支持传统错误处理|强制使用异常处理|强制使用异常处理| | ||
|标准库|标准库功能强大,但需要额外的库进行扩展|标准库提供丰富的功能,如集合、并发等|标准库提供丰富的功能,有大量第三方库支持| | ||
|编译方式|编译为机器码或字节码|编译为中间语言(IL),由JIT编译器运行时编译|解释执行,无需编译| | ||
|适用领域|系统/应用软件、游戏开发、嵌入式系统|桌面应用、Web应用、移动应用、游戏开发|Web开发、数据分析、机器学习、脚本编写| | ||
|社区支持|社区庞大,历史悠久|社区活跃,由微软支持|社区庞大,快速增长| | ||
|开发效率|相对较低,编译时间可能较长|相对较高,IDE支持良好|非常高,快速迭代和开发| | ||
|
||
以上是这些语言之间的比较,C++性能最高,Python性能最低,但是Python使用非常简单,有非常多的库可以调用,这使得人们根本不想用C++去做AI方面的研究。 | ||
|
||
## 代码对比,以统计单词次数为例 | ||
|
||
C++: | ||
|
||
```cpp | ||
#include <iostream> | ||
#include <fstream> | ||
#include <sstream> | ||
#include <map> | ||
#include <string> | ||
|
||
int main() { | ||
std::map<std::string, int> word_count; | ||
std::ifstream file("example.txt"); | ||
std::string word; | ||
|
||
if (file.is_open()) { | ||
while (file >> word) { | ||
++word_count[word]; | ||
} | ||
file.close(); | ||
} else { | ||
std::cerr << "Unable to open file"; | ||
return 1; | ||
} | ||
|
||
for (const auto &pair : word_count) { | ||
std::cout << pair.first << ": " << pair.second << std::endl; | ||
} | ||
|
||
return 0; | ||
} | ||
|
||
``` | ||
|
||
C#: | ||
|
||
```csharp | ||
using System; | ||
using System.IO; | ||
using System.Collections.Generic; | ||
|
||
class Program | ||
{ | ||
static void Main() | ||
{ | ||
var wordCount = new Dictionary<string, int>(); | ||
string filePath = "example.txt"; | ||
|
||
try | ||
{ | ||
using (StreamReader sr = new StreamReader(filePath)) | ||
{ | ||
string line; | ||
while ((line = sr.ReadLine()) != null) | ||
{ | ||
string[] words = line.Split(new char[] { ' ', '\t' }, StringSplitOptions.RemoveEmptyEntries); | ||
foreach (string word in words) | ||
{ | ||
if (wordCount.ContainsKey(word)) | ||
{ | ||
wordCount[word]++; | ||
} | ||
else | ||
{ | ||
wordCount.Add(word, 1); | ||
} | ||
} | ||
} | ||
} | ||
|
||
foreach (KeyValuePair<string, int> pair in wordCount) | ||
{ | ||
Console.WriteLine($"{pair.Key}: {pair.Value}"); | ||
} | ||
} | ||
catch (Exception e) | ||
{ | ||
Console.WriteLine($"An error occurred: {e.Message}"); | ||
} | ||
} | ||
} | ||
|
||
``` | ||
|
||
Python: | ||
|
||
```py | ||
word_count = {} | ||
with open('example.txt', 'r') as file: | ||
for line in file: | ||
words = line.split() | ||
for word in words: | ||
word_count[word] = word_count.get(word, 0) + 1 | ||
|
||
for word, count in word_count.items(): | ||
print(f"{word}: {count}") | ||
|
||
``` | ||
|
||
## 对比和优势 | ||
|
||
* **简洁性**:Python代码通常更短,更直观。这个例子很好地展示了如何用更少的代码行完成相同的任务。 | ||
* **可读性**:Python的语法设计使得代码更容易阅读和理解,特别是对于初学者。 | ||
* **标准库**:Python的标准库提供了大量的内置功能,使得完成一些常见任务(如文件处理、数据结构操作等)变得非常简单。 | ||
* **上下文管理器**:Python的`with`语句自动处理资源的打开和关闭,减少了出错的可能性,而在C++中需要手动管理资源。 | ||
|
||
# 在AI方面 | ||
|
||
在深度学习模型训练方面,C++、C#、Python三种编程语言提供了不同程度的支持,下面是基于这些方面的分析: | ||
|
||
## 1. 读图和数据预处理 | ||
|
||
- **C++**: C++通常不是进行数据预处理和读图的首选语言,但可以使用OpenCV等库进行图像处理。在编码正确的情况下,和Python一致。 | ||
|
||
- **C#**: C#在数据预处理方面不如Python丰富,但可以通过Emgu CV(一个OpenCV的.NET接口)进行图像处理。在编码正确的情况下,和Python一致。 | ||
|
||
- **Python**: Python是数据预处理和读图的首选语言,拥有大量的库和框架,如Pillow、OpenCV、scikit-image(图像处理),Pandas(数据处理),NumPy(数值计算)等,这些都极大地简化了数据预处理的工作。 | ||
|
||
## 2. 使用显卡训练 | ||
|
||
- **C++**: C++可以直接调用CUDA或OpenCL等低级API来利用GPU进行计算,但这需要相对较高的专业知识。简单来说就是非常难写。 | ||
|
||
- **C#**: C#对于直接使用GPU较为不便,虽然有一些库(如Alea GPU)可以实现这一点,但并不如C++或Python中的解决方案成熟。 | ||
|
||
- **Python**: Python通过TensorFlow、PyTorch等深度学习框架提供了对GPU的高级抽象,使得使用GPU进行训练变得非常简单,并且效率非常高。这些框架背后通常都是用C++写的底层实现,确保了性能。 | ||
|
||
## 3. 反向传播和矩阵乘法 | ||
|
||
- **C++**: C++在执行矩阵乘法和反向传播等操作时通常需要直接使用BLAS(基础线性代数程序集)或手动实现,这对于非专业人士来说非常困难。 | ||
|
||
- **C#**: C#中,进行矩阵乘法和反向传播等操作通常依赖于第三方库,如`Math.NET Numerics`,但在深度学习方面的支持不如Python丰富。 | ||
|
||
- **Python**: Python通过NumPy提供高效的矩阵操作,而在深度学习框架如TensorFlow和PyTorch中,反向传播和矩阵乘法等操作都是自动化和优化的,开发者无需手动实现。 | ||
|
||
## 4. Tensor操作 | ||
|
||
- **C++**: C++中的Tensor操作通常需要依赖于特定的深度学习库,如 LibTorch 的 C++ API,但这些API相比于Python版本通常更难使用和维护。 | ||
|
||
- **C#**: C#中的Tensor操作不如Python或C++那样成熟,虽然有一些尝试(如SciSharp STACK的`TensorFlow.NET`)来桥接这个差距,但整体生态仍然有限。 | ||
|
||
- **Python**: Python是进行Tensor操作的首选语言,TensorFlow、PyTorch等框架提供了强大而灵活的Tensor操作API,使得深度学习模型的构建和训练变得非常简单。 | ||
|
||
## 5. 统计结果和可视化 | ||
|
||
- **C++**: C++在统计和可视化方面的库较少,通常需要将数据导出到Python等其他语言进行进一步的分析和可视化。 | ||
|
||
- **C#**: C#有一些用于数据分析和可视化的库,如OxyPlot和Deedle,但在深度学习领域的应用相对较少。 | ||
|
||
- **Python**: Python在统计结果和可视化方面拥有强大的库,如Matplotlib、Seaborn、Plotly等,这些库能够方便地展示深度学习模型的训练过程和结果。 | ||
|
||
Python因其丰富的库和框架,成为了深度学习模型训练的首选语言。C++和C#在某些方面可能提供更高的性能或特定的应用,但在易用性、社区支持和生态丰富度方面通常不如Python。 | ||
|
||
# 动态类型 | ||
|
||
**Python** 是一种动态类型语言,这意味着变量的类型是在运行时决定的,而不是在编译时。这为开发者提供了极大的灵活性和速度,使得快速原型设计和迭代变得更加容易。在深度学习模型训练中,这种灵活性尤其有用,因为模型的结构和数据类型可能会频繁变化。 | ||
|
||
**C++** 和 **C#** 通常被认为是静态类型语言,这意味着变量的类型在编译时就已经确定。这种类型的确定性有助于捕捉类型错误和优化性能,但可能会减慢开发速度,特别是在需要频繁修改和试验模型结构的深度学习领域。 | ||
|
||
比如 Python 写的加法函数: | ||
|
||
```py | ||
def add(a, b): | ||
return a + b | ||
|
||
# 可以传入整数 | ||
print(add(1, 2)) # 输出: 3 | ||
|
||
# 也可以传入字符串 | ||
print(add("Hello, ", "world!")) # 输出: Hello, world! | ||
|
||
# 甚至可以传入列表 | ||
print(add([1, 2], [3, 4])) # 输出: [1, 2, 3, 4] | ||
``` | ||
|
||
下面是 C++ 写的加法函数: | ||
|
||
```cpp | ||
#include <iostream> | ||
#include <string> | ||
#include <vector> | ||
|
||
// 整数加法 | ||
int add(int a, int b) { | ||
return a + b; | ||
} | ||
|
||
// 字符串加法 | ||
std::string add(std::string a, std::string b) { | ||
return a + b; | ||
} | ||
|
||
// 整数列表加法函数 | ||
std::vector<int> addIntLists(const std::vector<int>& a, const std::vector<int>& b) { | ||
// 创建一个新的vector,初始容量为a和b的元素总和,以提高效率 | ||
std::vector<int> result; | ||
result.reserve(a.size() + b.size()); | ||
|
||
// 将a的所有元素添加到result | ||
result.insert(result.end(), a.begin(), a.end()); | ||
// 将b的所有元素添加到result | ||
result.insert(result.end(), b.begin(), b.end()); | ||
|
||
return result; | ||
} | ||
|
||
|
||
int main() { | ||
// 整数加法 | ||
std::cout << add(1, 2) << std::endl; // 输出: 3 | ||
|
||
// 字符串加法 | ||
std::cout << add("Hello, ", "world!") << std::endl; // 输出: Hello, world! | ||
|
||
// 整数列表加法 | ||
std::vector<int> list1 = {1, 2, 3}; | ||
std::vector<int> list2 = {4, 5, 6}; | ||
std::vector<int> result = addIntLists(list1, list2); | ||
|
||
// 打印结果 | ||
std::cout << "Result: "; | ||
for (int elem : result) { | ||
std::cout << elem << " "; | ||
} | ||
std::cout << std::endl; | ||
|
||
return 0; | ||
} | ||
``` | ||
Python 的加法函数,写一个函数就可以适用所有支持+运算的数据类型,但是C++的函数,整数要写一个,字符串要写一个,列表还要写更复杂的代码才能相加。 | ||
而如果你要支持 float 类型的列表相加,还要再写一个函数才可以。这对开发者来说太麻烦了。 | ||
对于简单的数据类型都需要这样写,如果是不同的模型对象,训练的代码就需要设计更加复杂的模板函数去兼容,时间都浪费在写代码上了。而对 Python 来说只需要写一套训练流程,即可适应各种不同的模型,只要它们都有forward函数和backward函数即可,所以动态类型对深度学习是非常有必要的。 | ||
下面是一个简单的模型训练过程: | ||
```py | ||
def train(dataloader, model, loss_fn, optimizer): | ||
model.train() | ||
for batch, (X, y) in enumerate(dataloader): | ||
X, y = X.to(device), y.to(device) | ||
# 计算 Loss | ||
pred = model(X) | ||
loss = loss_fn(pred, y) | ||
# 反向传播优化模型 | ||
loss.backward() | ||
optimizer.step() | ||
optimizer.zero_grad() | ||
``` | ||
|
||
该训练流程适应所有 PyTorch 搭建的模型。 | ||
|
||
参考链接:[https://pytorch.org/tutorials/beginner/basics/quickstart_tutorial.html](https://pytorch.org/tutorials/beginner/basics/quickstart_tutorial.html) | ||
|
||
# 一个巨星的陨落 | ||
|
||
在 YOLO、YOLOv2、YOLOv3 时代,有一个著名的深度学习训练框架叫 [Darknet](https://github.com/pjreddie/darknet),它是使用 C 和 CUDA 编写的,作者于2018年放弃了该框架的更新,目前在它的主页写着 [YOLOv7](https://github.com/WongKinYiu/yolov7) 的广告,它是由 PyTorch 编写的: | ||
|
||
![yolo](why-use-python/image-1.png) | ||
|
||
在 YOLOv3之后,所有的 YOLO 都是 PyTorch 写的: | ||
|
||
* YOLOv4:[https://github.com/WongKinYiu/PyTorch_YOLOv4](https://github.com/WongKinYiu/PyTorch_YOLOv4) | ||
* YOLOv5:[https://github.com/ultralytics/yolov5](https://github.com/ultralytics/yolov5) | ||
* YOLOv6:[https://github.com/meituan/YOLOv6](https://github.com/meituan/YOLOv6) | ||
* YOLOv7:[https://github.com/WongKinYiu/yolov7](https://github.com/WongKinYiu/yolov7) | ||
* YOLOv8:[https://github.com/ultralytics/ultralytics](https://github.com/ultralytics/ultralytics) | ||
* YOLOv9:[https://github.com/WongKinYiu/yolov9](https://github.com/WongKinYiu/yolov9) | ||
|
||
# 总结 | ||
|
||
在这个星球上,大多数AI研究员都使用 Python 编写他们的模型和算法,如果你不会 Python,几乎无法从事 AI 算法的开发,因此我们选择使用 Python 开发我们的算法,以及配套的软件,只有推理框架选择使用 C++ 来开发。 |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters