私は非ベクトル化と半ベクトル化の方法でstdを計算しようとしています。 ベクトル化されていないバージョンのコードは正常に機能しますが、半ベクトル化されたバージョンも同様に機能しますが、生成される結果は同じではありません。
これはバージョン1:このスニペットで同じ標準偏差が生成されないのはなぜですか?
import math
#unvectorized version --really slow!
def calc_std_classic(a):
batch = a.shape[0]
channel = a.shape[1]
width = a.shape[2]
height = a.shape[3]
mean = calc_mean_classic2(data_train)
sum = np.zeros((channel))
for i in range(batch):
for j in range(channel):
for w in range(width):
for h in range(height):
sum[j] += (abs(a[i,j,w,h] - mean[j])**2)
var = (sum/(width*height*batch))
return [(math.sqrt(x)) for x in var ]
半ベクトル:
def calc_std_classic2(a):
batch = a.shape[0]
channel = a.shape[1]
width = a.shape[2]
height = a.shape[3]
mean = calc_mean_classic2(data_train)
sum = np.zeros((channel))
for i in range(batch):
for j in range(channel):
sum[j] += np.sum(abs(a[i,j,:,:] - mean[j])**2)
var = (sum/(width*height*batch))
return [(math.sqrt(x)) for x in var ]
、これはその必要に応じて平均算出する方法である:
def calc_mean_classic2(a):
#sum all elements in each channel and divide by the number of elements
batch = a.shape[0]
channel = a.shape[1]
width = a.shape[2]
height = a.shape[3]
sum = np.zeros((channel))
for i in range(batch):
for j in range(channel):
sum[j] += np.sum(a[i,j,:,:])
return (sum/(width*height*batch))
ニシキヘビを使用して生成された出力numpy.std()であり、2つの方法は次のとおりです。
std = np.std(data_train, axis=(0,2,3))
std2 = calc_std_classic(data_train)
std3 = calc_std_classic2(data_train)
が発生:
std = [ 62.99321928 62.08870764 66.70489964]
std2 = [62.99321927774396, 62.08870764038716, 66.7048996406483]
std3 = [62.99321927813685, 62.088707640014405, 66.70489964063101]
あなたが見ることができるように、すべての3つは、8桁まで同じ結果を生成します。 3番目の方法では残りの数字が異なります。
私はここで間違っていますか?
おそらくnumpyはより安定した合計アルゴリズムを使用します。 –
@WillemVanOnsem:それはすべてですか? 私が行っている手順は正しいですか? – Breeze
投票が遅れましたか?なぜ誰かがこの質問をdownvoteだろうか?どうしたの ? – Breeze