pythonnumpy關系
1. 為什麼python中的NumPy會多進程並行載入數據,而且返回的結果卻是相同的
明敏 發自 凹非寺
量子位 報道 | 公眾號 QbitAI
到底是怎樣的一個bug,能讓95%的Pytorch庫中招,就連特斯拉AI總監深受困擾?
還別說,這個bug雖小,但有夠「狡猾」的。
這就是最近Reddit上熱議的一個話題,是一位網友在使用再平常不過的Pytorch+Numpy組合時發現。
最主要的是,在代碼能夠跑通的情況下,它甚至還會影響模型的准確率!
除此之外,網友熱議的另外一個點,竟然是:
而是它到底算不算一個bug?
這究竟是怎麼一回事?
事情的起因是一位網友發現,在PyTorch中用NumPy來生成隨機數時,受到數據預處理的限制,會多進程並行載入數據,但最後每個進程返回的隨機數卻是相同的。
他還舉出例子證實了自己的說法。
如下是一個示例數據集,它會返回三個元素的隨機向量。這里採用的批量大小分別為2,工作進程為4個。
然後神奇的事情發生了:每個進程返回的隨機數都是一樣的。
這個結果會著實讓人有點一頭霧水,就好像數學應用題求小明走一段路程需要花費多少時間,而你卻算出來了負數。
發現了問題後,這位網友還在GitHub上下載了超過10萬個PyTorch庫,用同樣的方法產生隨機數。
結果更加令人震驚:居然有超過95%的庫都受到這個問題的困擾!
這其中不乏PyTorch的官方教程和OpenAI的代碼,連特斯拉AI總監Karpathy也承認自己「被坑過」!
但有一說一,這個bug想要解決也不難:只需要在每個epoch都重新設置seed,或者用python內置的隨機數生成器就可以避免這個問題。
到底是不是bug?
如果這個問題已經可以解決,為什麼還會引起如此大的討論呢?
因為網友們的重點已經上升到了「哲學」層面:
這到底是不是一個bug?
在Reddit上有人認為:這不是一個bug。
雖然這個問題非常常見,但它並不算是一個bug,而是一個在調試時不可以忽略的點。
就是這個觀點,激起了千層浪花,許多人都認為他忽略了問題的關鍵所在。
這不是產生偽隨機數的問題,也不是numpy的問題,問題的核心是在於PyTorch中的DataLoader的實現
對於包含隨機轉換的數據載入pipeline,這意味著每個worker都將選擇「相同」的轉換。而現在NN中的許多數據載入pipeline,都使用某種類型的隨機轉換來進行數據增強,所以不重新初始化可能是一個預設。
另一位網友也表示這個bug其實是在預設程序下運行才出現的,應該向更多用戶指出來。
並且95%以上的Pytorch庫受此困擾,也絕不是危言聳聽。
有人就分享出了自己此前的慘痛經歷:
我認識到這一點是之前跑了許多進程來創建數據集時,然而發現其中一半的數據是重復的,之後花了很長的時間才發現哪裡出了問題。
也有用戶補充說,如果 95% 以上的用戶使用時出現錯誤,那麼代碼就是錯的。
順便一提,這提供了Karpathy定律的另一個例子:即使你搞砸了一些非常基本代碼,「neural nets want to work」。
你有踩過PyTorch的坑嗎?
如上的bug並不是偶然,隨著用PyTorch的人越來越多,被發現的bug也就越來越多,某乎上還有PyTorch的坑之總結,被瀏覽量高達49w。
其中從向量、函數到model.train(),無論是真bug還是自己出了bug,大家的血淚史還真的是各有千秋。
所以,關於PyTorch你可以分享的經驗血淚史嗎?
歡迎評論區留言討論~
參考鏈接:
[1]https://tanelp.github.io/posts/a-bug-that-plagues-thousands-of-open-source-ml-projects/
[2]https://www.reddit.com/r/MachineLearning/comments/mocpgj/p_using_pytorch_numpy_a_bug_that_plagues/
[3]https://www.hu.com/question/67209417/answer/866488638
— 完 —
2. python關於numpy基礎問題
Python發展至今,已經有越來越多的人使用python進行科學技術,NumPY是python中的一款高性能科學計算和數據分析的基礎包。
ndarray
ndarray(以下簡稱數組)是numpy的數組對象,需要注意的是,它是同構的,也就是說其中的所有元素必須是相同的類型。其中每個數組都有一個shape和dtype。
shape既是數組的形狀,比如
復制代碼
1 import numpy as np
2 from numpy.random import randn
3
4 arr = randn(12).reshape(3, 4)
5
6 arr
7
8 [[ 0.98655235 1.20830283 -0.72135183 0.40292924]
9 [-0.05059849 -0.02714873 -0.62775486 0.83222997]
10 [-0.84826071 -0.29484606 -0.76984902 0.09025059]]
11
12 arr.shape
13 (3, 4)
復制代碼
其中(3, 4)即代表arr是3行4列的數組,其中dtype為float64
一下函數可以用來創建數組
array將輸入數據轉換為ndarray,類型可制定也可默認
asarray將輸入轉換為ndarray
arange類似內置range
ones、ones_like根據形狀創建一個全1的數組、後者可以復制其他數組的形狀
zeros、zeros_like類似上面,全0
empty、empty_like創建新數組、只分配空間
eye、identity創建對角線為1的對角矩陣
數組的轉置和軸對稱
轉置是多維數組的基本運算之一。可以使用.T屬性或者transpose()來實現。.T就是進行軸對換而transpose則可以接收參數進行更豐富的變換
復制代碼
arr = np.arange(6).reshape((2,3))
print arr
[[0 1 2]
[3 4 5]]
print arr.T
[[0 3]
[1 4]
[2 5]]
arr = np.arange(24).reshape((2,3,4))
print arr
[[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]]
[[12 13 14 15]
[16 17 18 19]
[20 21 22 23]]]
print arr.transpose((0,1,2))
[[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]]
[[12 13 14 15]
[16 17 18 19]
[20 21 22 23]]]
復制代碼
數組的運算
大小相等的數組之間做任何算術運算都會將運算應用到元素級別。
復制代碼
1 arr = np.arange(9).reshape(3, 3)
2 print arr
3
4 [[0 1 2]
5 [3 4 5]
6 [6 7 8]]
7
8 print arr*arr
9
10 [[ 0 1 4]
11 [ 9 16 25]
12 [36 49 64]]
13
14 print arr+arr
15
16 [[ 0 2 4]
17 [ 6 8 10]
18 [12 14 16]]
19
20 print arr*4
21
22 [[ 0 4 8]
23 [12 16 20]
24 [24 28 32]]
復制代碼
numpy的簡單計算中,ufunc通用函數是對數組中的數據執行元素級運算的函數。
如:
復制代碼
arr = np.arange(6).reshape((2,3))
print arr
[[0 1 2]
[3 4 5]]
print np.square(arr)
[[ 0 1 4]
[ 9 16 25]]
復制代碼
類似的有:abs,fabs,sqrt,square,exp,log,sign,ceil,floor,rint,modf,isnan,isfinite,isinf,cos,cosh,sin,sinh,tan,tanh,
add,subtract,multiply,power,mod,equal,等等
3. 圖解Python中數據分析工具包:Numpy
numpy是我學習python遇到的第一個第三方工具包,它可以讓我們快速上手數據分析。numpy提供了向量和矩陣計算和處理的大部分介面。目前很多python的基礎工具包都是基於numpy開發而來,比如 scikit-learn, SciPy, pandas, 還有 tensorflow。 numpy可以處理表格、圖像、文本等數據,極大地方便我們處理和分析數據。本文主要內容來自於Jay Alammar的一篇文章以及自己學習記錄。
原文地址: https://jalammar.github.io/visual-numpy/
使用過程中,如果希望 Numpy 能創建並初始化數組的值, Numpy 提供了 ones()、zeros() 和 random.random() 等方法。只需傳遞希望生成的元素數量(大小)即可:
還可以進行如下操作:
一般,需要數組和單個數字之間也可以進行運算操作(即向量和標量之間的運算)。比如說 data * 1.6 ,numpy利用一個叫做廣播機制(broadcasting)的概念實現了這一運算。:
我們可以通過索引對numpy數據獲取任意位置數據或者對數據切片
我們可以通過numpy自帶的函數對數據進行一些想要的聚合計算,比如min、max 和 sum ,還可以使用 mean 得到平均值,使用 prod 得到所有元素的乘積,使用 std 得到標准差等等。
上述操作不僅可以應用於單維度數據,還可以用於多維度數據{(矩陣)。
同樣可以使用ones()、zeros() 和 random.random()創建矩陣,只要寫入一個描述矩陣維數的元組即可:
numpy還可以處理更高維度的數據:
創建更高維度數據只需要在創建時,在參數中增加一個維度值即可:
根據數組中數值是否滿足條件,輸出為True或False.
希望得到滿足條件的索引,用np.where函數實現.
根據索引得到對應位置的值.
np.where也可以接受另兩個可選擇的參數a和b。當條件滿足時,輸出a,反之輸出b.
獲取數組最大值和最小值的索引可以使用np.argmax和np.argmin.
1、numpy.tofile()和numpy.fromfile()
保存為二進制格式,但是不保存數組形狀和數據類型, 即都壓縮為一維的數組,需要自己記錄數據的形狀,讀取的時候再reshape.
2、numpy.save() 和 numpy.load()
保存為二進制格式,保存數組形狀和數據類型, 不需要進行reshape
實例:
3、numpy.savetxt()和numpy.loadtxt()
np.savetxt(fname,array,fmt=』%.18e』,delimiter=None)
Parameter解釋:
array:待存入文件的數組。
fmt:寫入文件的格式
實例:
4. python數據分析模塊:numpy、pandas全解
一維數組情況:
二維數組情況:
3參數情況:
2參數情況:
1參數情況:
一維情況:
二維情況:
一維情況:
二維情況:
一維情況:
二維情況:第三個參數指定維度
只查看行數、或者列數
逗號隔開兩個索引
某些行
某些列
可以看出append()函數在二維數組中添加元素,結果轉為了一維數組。
那怎麼保持二維數組呢?可以設置axis參數按行或者按列添加
可以看出先把二維數組降成了一維數組,再在索引為1的位置添加元素。
那麼怎麼保持在二維添加元素呢? 同樣設置axis參數
也分按行和按列刪除
標記缺失值: isnan()函數
補充缺失值:
同樣axis參數可以指定拼接按行還是按列
2. hstack()函數:以水平堆疊的方式拼接數組
3. vstack()函數:以垂直堆疊的方式拼接數組
第二個參數還可以是數組,指定拆分的位置
hsplit()函數:橫向拆成幾個數組
vsplit()函數:縱向拆成幾個數組
數組與數組之間的運算
數組與數值的運算
可以指定整個數組求和,還是按行或者按列
axis=0:每一列的元素求和
axis=1:每一行的元素求和
axis=0:每一列求均值
axis=1:每一行求均值
axis=0:每一列求最大值
axis=1:每一行求最大值
pandas有兩個重要的數據結構對象:Series和DataFrame。
Series是創建一個一維數組對象,會自動生成行標簽。
會自動生成行列標簽
也可以用字典形式生成數據
在用字典生成數據的基礎上,同時指定行標簽
例如對下表的數據進行讀取
4月是第四個表,我們應把sheet_name參數指定為3;因為索引是從0開始的。
可以看出read_excel()函數自動創建了一個DataFrame對象,同時自動把第一行數據當做列標簽。
可以看出不給出header參數時,該參數默認為0。
header=1時結果如下:
header=None時結果如下:
index_col=0時,第0列為列標簽
index_col=0時
usecols=[2]:指定第二列
指定多列
數據如下:
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-j1SHxY8y-1637655972909)(C: ypora-user-imagesimage-20211114192949607.png)]
nrows=3時
head()函數中參數為空默認前5行
指定head(3)時如下
numpy模塊也是shape
查看特定列的書庫類型
特定列數據類型轉換
先查看一下所有數據
與單行相比,結果顯示的格式不一樣了
iloc()挑選:
或者給出區間
挑選數據要麼標簽,要麼索引挑選
或者
或者寫成區間
標簽挑選
或者索引挑選
先查看一下數據
或者用字典一對一修改
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-a6QKIoie-1637655972912)(C: ypora-user-imagesimage-20211123110431201.png)]
isin()函數查看錶中是否有該值
查看特定列是否有該值
可以看出上述代碼並沒有替換,那怎麼替換呢?
末尾插入一列
指定插入到哪列
axis參數可以指定刪除行還是刪除列
指定標簽刪除
指定索引刪除
方法三
指定行標簽刪除
指定索引刪除
方法三:
先查看所有數據
info()函數查看數據類型,還可以查看是否有缺失值
isnull()函數查看是否有缺失值
在numpy模塊中用isnan()函數
刪除有缺失值的行
刪除整行都為缺失值的行: 需要指定how參數
不同列的缺失值設置不同的填充值
默認保留第一個重復值所在的行,刪除其他重復值所在的行
保留第一個重復值所在的行
保留最後一個重復值所在的行
是重復的就刪除
降序如下
參數指定first時,表示在數據有重復值時,越先出現的數據排名越靠前
獲取產品為單肩包的行數據
獲取數量>60的行數據
獲取產品為單肩包 且 數量>60 的行數據
獲取產品為單肩包 或 數量>60 的行數據
stack()函數轉換成樹形結構
how參數指定外連接
on參數指定按哪一列合並
concat()函數採用 全連接 的方式,沒有的數設置為缺失值
重置行標簽
效果與concat()一樣
末尾添加行元素
指定列求和
指定列求均值
指定列求最值
獲取單列的
corr()函數獲取相關系數
獲取指定列與其他列的相關系數
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-46g9qgQw-1637655972913)(C: ypora-user-imagesimage-20211123135643804.png)]
groupby()函數返回的是一個DataFrameBy對象,該對象包含分組後的數據,但是不能直觀地顯示出來。
分組後獲取指定列的匯總情況
獲取多列的匯總情況
獲取多列的情況
ta = pd.read_excel(『相關性分析.xlsx』)
print(data)
corr()函數獲取相關系數
獲取指定列與其他列的相關系數
[外鏈圖片轉存中…(img-46g9qgQw-1637655972913)]
groupby()函數返回的是一個DataFrameBy對象,該對象包含分組後的數據,但是不能直觀地顯示出來。
分組後獲取指定列的匯總情況
獲取多列的匯總情況
獲取多列的情況
5. python numpy有什麼用
NumPyis the fundamental package for scientific computing withPython。就是科學計算包。
a powerful N-dimensional array object
sophisticated (broadcasting) functions
tools for integrating C/C++ and Fortran code
useful linear algebra, Fourier transform, and random number capabilities
一個用python實現的科學計算包。包括:1、一個強大的N維數組對象Array;2、比較成熟的(廣播)函數庫;3、用於整合C/C++和Fortran代碼的工具包;4、實用的線性代數、傅里葉變換和隨機數生成函數。numpy和稀疏矩陣運算包scipy配合使用更加方便。
NumPy系統是Python的一種開源的數字擴展。這種工具可用來存儲和處理矩陣,比Python自身的嵌套列表結構要高效。據說NumPy將Python相當於變成一種免費的更強大的MatLab系統。
6. python怎樣引用numpy
numpy是python的一個科學計算的庫,提供了矩陣運算的功能,一般與scipy、matplotlib一起使用。
導入numpy的範例如下:
>>>import numpy as np
>>>print np.version.version
1.6.2