1

私はタプルを持っています。最初の要素はfloatで、2番目の要素は浮動小数点数を含むより多くのネストされたリストを持つリストです(これらの値の意味を心配しないでください)。なぜタプルの値が変わるのですか(Python)?

(0.2742965753780876, [[[33.119], [-8.326]], [[-34.084, -4.385], [-3.047, 18.546], [-10.757, 0.573], [21.395, 23.937], [5.011, -5.234]], [[-23.434, 9.989, 9.113, -23.253, 11.86], [-56.818, 4.771, -3.383, -27.143, 4.81], [-6.564, -40.132, -2.223, -2.663, -10.231], [-2.05, -15.989, 4.369, -20.051, 4.657]], [[-10.868, -39.934, 0.465, 38.103]], [-0.889, 1.129, 0.743]]) 
(0.2742965753780876, [[[21.633], [-8.972]], [[-35.754, -13.243], [-0.718, 17.724], [-16.452, 6.619], [24.151, 25.037], [1.76, -7.891]], [[-26.011, 9.072, 14.685, -20.044, 10.612], [-55.53, -0.131, 0.15, -27.031, 8.03], [-3.225, -36.499, -2.558, 0.253, -8.292], [-1.274, -22.561, 0.431, -23.405, 6.808]], [[-13.668, -47.758, -6.489, 43.27]], [-0.889, 1.129, 0.743]]) 
(0.2742965753780876, [[[22.435], [-6.71]], [[-47.591, -8.998], [-1.134, 16.529], [-16.399, 4.369], [23.344, 24.72], [2.175, -14.129]], [[-26.603, 11.472, 9.433, -21.13, 9.759], [-50.109, 1.084, 1.256, -18.826, 9.588], [-6.935, -27.957, 9.045, 1.291, 2.27], [-1.336, -29.908, -0.3, -27.242, 4.555]], [[-12.933, -42.377, 4.077, 38.864]], [-0.889, 1.129, 0.743]]) 
(0.2742965753780876, [[[26.688], [-4.315]], [[-49.478, -4.214], [0.116, 20.39], [-14.691, 3.496], [15.367, 23.116], [18.075, -2.748]], [[-25.588, 6.249, 4.364, -20.727, 19.639], [-55.524, -2.901, 4.639, -11.759, 11.794], [-8.633, -25.316, 11.841, 1.492, 1.36], [-0.797, -26.306, 1.379, -16.266, -0.291]], [[-24.726, -46.726, 12.765, 38.977]], [-0.889, 1.129, 0.743]]) 
(0.2742965753780876, [[[21.776], [-8.466]], [[-47.66, -5.868], [1.855, 23.062], [-19.521, 18.331], [29.251, 25.491], [21.32, -5.379]], [[-36.199, 7.786, -1.48, -27.042, 14.769], [-61.468, -12.218, -10.307, -6.156, 8.287], [-17.785, -33.124, 16.564, 2.249, -0.675], [-4.391, -18.11, 7.349, -9.234, -2.31]], [[-23.139, -55.043, 9.106, 35.827]], [-0.889, 1.129, 0.743]]) 

これらの値は、人工ニューラルネットワークをトレーニングする遺伝的アルゴリズムによって得られたものである。ご覧のとおり、私は5世代のトップタプルを投稿しました。 MLに慣れている場合、最初の要素はトレーニングデータの分類でANNが生成する平均二乗誤差であり、2番目はその誤差に関連するANNの重みのリストです。

私は新しい世代を作成するたびに、新しいタプルを取得して新しい候補のリストに戻します。そのため、上記のエラーが何度か現れたのです。それは各世代のトップ候補でした。

ただし、私の問題を理解するためにこれを知る必要はありません。

重要なことは、遺伝的アルゴリズム関数を使用して新しい世代を実行するたびに、先頭のエラー(最初の要素)が変更されない可能性があることです。アルゴリズムがより良い解決策を見つけられなかったことを意味するため、これは正常です。もちろん、重み(2番目の要素)も変更しないでください。そうした場合、まったく異なるエラーが発生するためです。

残念ながら、これは当てはまりません。私のタプル内のデータは何とか変更されています。上記のプリントアウトからわかるように、私が新しい世代を走るたびに、エラーは同じままですが、ウェイトが変わります。

これはなぜですか?なぜタプルの値が変わるのでしょうか?

ここで私のコードのいくつかを見ていきます。これは突然変異を生成するためのコードです。 mutate()メソッドは、重み(浮動小数点数)のリストをステップ実行し、それらの重みに対して小さなランダムな増分を行います。重みを変更したり、エラーを更新したりする意味がないため、0.2742965753780876に行っていることです。タプルは不変なので、それは可能ではありません。

for i in range(10): 
    mList = weightList[random.randint(0,4)][1] # pick a set of weights from the top 5 
    newList = mutate(mList, weightList[0][0]) # create a new list by mutating certain values of the unmutated list 
    n.setWeights(listToGenome(newList,n)) # give the ANN the new weights 
    error = trainSine(n) # train the network on the training set and return the mean-squared error 
weightList.append((error, child)) 

また、私は新しい世代の作成が完了していますたびに、私は自分のエラーでリストをソートし、次の世代に継続してトップ10候補者を選ぶことを知ってほしいことがあります。

errorList.sort() 
for i in range(10): 
    survivorList.append(errorList[i]) 

それはそれです。もちろん、もっと多くのコードがありますが、誰かがそれを必要とするなら、私はそれを共有します。何か案は?

+6

あなたの含まれているリストは*まだ変更可能なオブジェクト*であり、それらをタプルの間で共有しています。代わりにそれらのコピーを作成する必要があります。 –

+2

サイドノート:あなたのすべての世代をソートするのではなく、['heapq.nsmallest()'関数を使ってトップ10だけを選ぶためにheapqを使います(https://docs.python.org/2/library/heapq .html#heapq.nsmallest): 'survivorList = heapq.nsmallest(10、errorList)'。これはより効率的です(ソートのためのheapqのKアイテムとO(NlogN)の選択のためのO(NlogK)) –

答えて

6

タプルは変更できませんが、内部のリストはまだ変更されていません。リストのディープコピーを行う必要があります。リストのコピーは、コピー時にすべての変数参照などがなくてもコピーされます。これはcopyモジュールで行うことができます。構文は次のとおりです。

import copy 
myList = [1, 5, 3, 9, 4] 
myOtherList = copy.deepcopy(myList) 

あなたがmyListを変更、またはmyList変更に貢献した変数のいずれかの場合、myOtherListが他とは独立して、同じままならば、上記のコードを使用します。

+0

これはまさに私が探していたものですが、まだ動作しません。私の価値観は変わり続けています。タプルを作成するたびに、常に正しい値が返されるので、実際には意味をなさない。 – user255919

+0

さて、私はそれを得たかもしれないと思います。関数が返す値のディープコピーだけでなく、ミューテータ関数内にパラメータのディープコピーを作成する必要があるようです。 – user255919

+0

@ user255919 喜んで助けになる! :-) –

関連する問題