레이블이 발생인 게시물을 표시합니다. 모든 게시물 표시
레이블이 발생인 게시물을 표시합니다. 모든 게시물 표시

창조론 이야기 - Émile Borel과 무한의 원숭이 정리

<전략>

예를 들어 여기 400개의 아미노산으로 구성되어져 있는 한 개의 단백질이 있다고 하면, 이 단백질이 우연히 생겨나기 위해서는 20개의 아미노산중에서 한개를 고를 확률 1/20을 400번 곱한 값 즉, 1/10520의 확률을 필요로 하게 된다. 한 계산에 의하면, 스스로 복제가 가능한 가장 단순한 가상적인 생명체가 존재하기 위해서는 400개의 아미노산으로 구성된 이 같은 단백질이 적어도 124개는 있어야 한다고 한다. 그렇다면, 이 같은 생물이 우연히 생겨나게 될 확률은 1/10520을 다시 124번 곱한 값 즉, 1/1064,480이 되게 된다. 그런데, 단백질을 구성하는 아미노산은 L과 D의 두 가지 다른 형태가 있는데, 생물체를 구성하는 단백질 속에는 오로지 L 형태의 아미노산만이 존재하고 있다. 따라서, 이제 앞서 우연히 생겨난 124개의 단백질이 동시에 모두 L 형태의 아미노산을 갖춘 단백질이 될 확률은 1/1078,616으로 계산되어진다. 생각해 보라, 숫자 10 뒤에 영이 78,616개가 나오는 숫자의 크기를. 확률학자 Emil Borel은 전 우주에 걸쳐 1/1050보다 작은 확률은 결코 일어날 수 없는 것과 같다고 했다. 하물며, 1/1078,616의 확률은 오죽하겠는가?


<후략>
출처 : 창조과학회


종종 이런 말을 하는 창조론자들이 있죠. 그런데 여기서 말하는 Emil Borel이란 사람이 누구일까요?

창조론 이야기 - 근거 根據 basis에서의 경험도 있지만 그래도 한번 찾아봤습니다.


역시나 마찬가지군요. 미리보기에서만 봐도 복사-붙임한 티가 팍팍 나는 게시물들 뿐입니다. 아마 원본은 이 글 처음에 인용한 창조과학회겠죠.

그런데 과연 저 말이 사실일까요? 에밀 보렐이란 학자에 대해 조사하다가 재미있는 사실을 발견했습니다.
에밀 보렐(Émile Borel)은 프랑스 수학자이자 정치가라고 하더군요. 다른 것은 생략하고 에밀 보렐의 논문 중 '무한의 원숭이 정리(infinite monkey theorem)'이란 것이 있습니다. 이것은 원숭이를 이용해서 일어나지 않을 듯한 사건의 발생을 상상하는 사고실험입니다.

한마리 원숭이가 타자기 앞에 앉아서 무작위로 자판을 두들깁니다. 이 원숭이가 셰익스피어 전집을 출력할 가능성은 몇일까요?
아마 0이라고 할 수 있겠죠.

하지만 에밀 보렐의 결론은, 수없이 많은 원숭이가 수없이 많은 시도를 한다면 셰익스피어 전집이 나올 가능성은 점점 커진다는 것입니다.

즉 무한한 수의 원숭이가 단 한번 타자기를 두들긴다면, 또는 한마리 원숭이가 무한한 횟수로 타자기를 두들긴다면 셰익스피어 전집이 아니라 전 세계 도서관의 모든 책을 출력할 확률은 100%라는 점입니다. 창조론 이야기 - 확률계산에서와 같은 방식으로 증명한 것이죠.

결국 에밀 보렐이란 사람은 창조론자들이 내세울 만한 사람이 아닙니다. 오히려 진화론 측에서 내세울 사람이죠. 에밀 보렐의 무한의 원숭이 정리(infinite monkey theorem)에서와 같이 지구 전체에 퍼진 유기물(수없이 많은 원숭이)과 10억년이라는 시간(수없이 많은 시도)이라면 창조론자들의 생각과는 달리 생명이 탄생할 가능성은 점점 커진다는 것이죠.
에밀 보렐을 언급하는 창조론자들은 자신이 자충수를 두고 있다는 사실을 알아야 할 것입니다.

GA - CNNC를 이용한 XOR 회로[2] - 유전자 설계

3. 유전자설계
신경망에서 하나의 노드에 필요한 정보는 다음과 같습니다.
① 입력스트림 : 입력노드들과 그 노드와의 연결 강도. float형의 벡터이며 그 크기로 연결강도를 표시합니다. 이 XOR회로에서는 16개의 채널을 준비합니다.
② Layer : 노드를 구분하기 위해 사용. Layer가 0보다 작으면 입력노드, 1보다 크면 출력노드, 그 사이면 은닉노드
③ Bias : 입력스트림의 하나로 만들 수도 있지만 여기서는 노드가 따로 가지고 있음
④ SigmoidFactor : 입력의 합을 출력으로 계산할때 시그모이드 팩터를 사용
XOR회로의 경우 하나의 CNNC는 2개의 입력노드, 1개의 출력노드(그 외에 몇개가 될지 모르는 은닉노드)로 구성됩니다. 초기상태에는 은닉노드가 없으므로 CNNC 하나의 유전자는

+1.1/Bias/SF(ABCDEFGHIJKLMNOP)(abcdefghijklmnop)
-0.1/Bias/SF(ABCDEFGHIJKLMNOP)(abcdefghijklmnop)
-0.2/Bias/SF(ABCDEFGHIJKLMNOP)(abcdefghijklmnop)

과 같습니다. 이 경우 Bias, SF(SigmoidFactor), A~P, a~p는 모두 float형입니다. 가장 앞의 숫자는 Layer이며 0 이하는 입력노드, 1 이상은 출력노드를 의미합니다. 뒤의 A~P, a~p의 리스트는 각각 송신채널, 수신채널입니다. 이 값이 0이면 그 채널로 송신/수신을 않는다는뜻이며 0이 아니라면 그 채널로 송수신을 한다는 뜻입니다.

procedure InitGene(Gene gene)
.. // 3개의 노드를 만듦
.. InitNode(gene.Node[0], -0.2)

.. InitNode(gene.Node[1], -0.1)
.. InitNode(gene.Node[2], 1.1)

.. // 입력과 출력노드 사이에 초기링크 만들기
.. MakeLink(gene.Node[0], gene.Node[2])
.. MakeLink(gene.Node[1], gene.Node[2])
end


procedure InitNode(Node node, double layer)
.. node.Layer = layer
.. node.Bias = Random(-5, 5)
.. node.SigmoidFactor = Random(0.001, 3)
.. for k := 0, 16 do
..... node.SendChannel[k] := 0
..... node.RecvChannel[k] := 0

.. end
end

procedure MakeLink(Node from, Node to)
.. channel := Random(0, 15)
.. from.SendChannel[channel] := Random(-5, 5)

.. to.RecvChannel[channel] := Random(-5, 5)
end

4. 발생(Ontogeny)
개념상으로는 앞에서 말한대로 채널을 통한 노드들간의 채널통신으로 이해했지만, 실제 적용하기 위해서는 기존의 신경망방식으로 바꾸는 것이 좋습니다. 즉 송신채널과 수신채널이 일치하는 노드들끼리 연결을 만드는 것입니다.
만약 두 노드의 송신채널과 수신채널이 동시에 0이 아닐 경우 두 노드 사이에는 연결이 생깁니다. 이 연결의 크기는 송신채널의 값과 수신채널의 값에 의해 결정됩니다.
아무리 송신채널이 강하게 송신해도(송신채널의 값이 커도) 수신채널에서 약하게 수신한다면(수신채널의 값이 작으면) 두 노드 사이의 연결강도는 약해집니다. 반대로 수신채널의 값이 커도 송신을 약하게 한다면(송신채널의 값이 작으면) 마찬가지로 연결은 약해지죠.
여기서는 두 채널값으로 연결의 강도를 계산하는 공식으로 기하평균을 사용했습니다. 기하평균은 다음과 같이 계산됩니다.



procedure Ontogeny(Gene gene, Brain brain)
.. // 각 노드에 해당하는 세포를 만듦
.. for k := 0, gene.NodeNumber do

..... brain.Cell[k].Layer := gene.Node[k].Layer
..... brain.Cell[k].Bias := gene.Node[k].Bias
..... brain.Cell[k].SigmoidFactor := gene.Node[k].SigmoidFactor
.. end

.. // 각 세포들 연결
.. for k := 0, brain.CellNumber do

..... for m := 0, brain.CellNumber do
........ // 링크정보를 알기 위해 brain.Cell[k,m]에 해당하는 노드를 찾음
........ nodek := FindNode(gene, brain.Cell[k])
........ nodem := FindNode(gene, brain.Cell[m])

........ // k와 m이 얼마만큼의 세기로 연결되어 있는지 확인
........ weigth = 0;
........ for c := 0, 16 do
........... mult := nodek.SendChannel[c] * nodem.RecvChannel[c]
........... if mult != 0 then
.............. gioavg := sqrt(mult)
// 기하평균 계산
.............. weigth := weigth + gioavg
........... end

........ end
..... MakeLink(brain.Cell[k], brain.Cell[m], weigth)

..... // k->m으로 강도 weigth의 입력 만듦
.. end
end

5. 적응도 계산
위에서 만들어진 brain을 가지고 적응도를 계산합니다. 자세한 알고리즘은 생략하겠지만, 입력셀에 랜덤으로 0/1을 넣고 신경망을 돌려 나온 값과 XOR계산값을 비교하여 그 차이가 작을수록 해당 CNNC의 적응도를 높이는 방식입니다. 임의의 입력값으로 100회를 반복한 후 결과를 최종 적응도로 결정했습니다.

단, 이때 출력에 따른 적응도함수를 다음과 같이 한다면 어떨까요?

.. output := think(a, b)
.. correct = a ^ b
.. if abs(correct - output) > 0.5 the
n
..... AddFitness(0)
.. else

..... AddFitness(10)
.. end


이 방식의 가장 큰 문제점은, 참값과의 차이가 0.51인(보다 적은 변이로 참값으로 갈 수 있는) 신경망과 0.9인 신경망 둘 다 적응도가 0으로써 둘 사이의 적응도 차이를 알 수 없다는 점입니다. 유전자알고리즘의 원칙인 조금이라도 더 적응도가 우수한 것을 찾을 수가 없는 것이죠. 그러므로 적응도함수는 반드시 꼭대기가 없는 경사함수가 되어야 합니다.
이 XOR 신경망에서는 다음과 같은 적응도 함수를 사용했습니다.

.. output := think(a, b)
.. correct
= a ^ b
.. diff = abs(output - correct)
.. subfit = 1 - diff // 차이가 작을수록 적응도 높아짐
.. AddFitness(subfit * subfit * 10)

그냥 subfit를 적응도로 사용해도 되지만 여기서는 참값에 가까와질수록 선택압을 높이기 위해 subfit의 제곱을 사용하여 오른쪽 그림과 같은 함수가 되었습니다.

각 XOR신경망에 대해 랜덤입력에 의한 적응도테스트를 100회 실시하여 그 합을 적응도로 간주, 재생산을 실시합니다.