gpt4 book ai didi

python - 遗传算法图像进化的不正确结果

转载 作者:太空狗 更新时间:2023-10-30 02:30:47 24 4
gpt4 key购买 nike

我正在尝试实现最初由 Roger Alsing 创建的程序.我对其他人实现的内容做了很多研究。我决定用 python 编写我的程序,并使用基本三角形作为形状。当我运行该程序时,经过更多代后它并没有显示出改进(三角形往往会消失)。我假设我的 mutate 函数有问题。谁能告诉我为什么它的结果不尽如人意?

我的代码:

import random
import copy
from PIL import Image, ImageDraw

optimal = Image.open("mona_lisa.png")
optimal = optimal.convert("RGBA")

size = width, height = optimal.size

num_shapes = 128

generations = 50000

def random_genome():
elements = []

for i in range(num_shapes):
x = (random.randint(0, width), random.randint(0, height))
y = (random.randint(0, width), random.randint(0, height))
z = (random.randint(0, width), random.randint(0, height))
r = random.randint(0, 255)
g = random.randint(0, 255)
b = random.randint(0, 255)
alpha = random.randint(10, 255)

elements.append([x, y, z, r, g, b, alpha])

return elements

def render_daughter(dna):
image = Image.new("RGBA", (width, height), "white")
draw = ImageDraw.Draw(image)

for item in dna:
x = item[0]
y = item[1]
z = item[2]
r = item[3]
g = item[4]
b = item[5]
alpha = item[6]

color = (r, g, b, alpha)

draw.polygon([x, y, z], fill = color)

return image

def mutate(dna):
dna_copy = copy.deepcopy(dna)

shape_index = random.randint(0, len(dna) - 1)
roulette = random.random() * 2

if roulette < 1:

if roulette < 0.25:
dna_copy[shape_index][3] = int(random.triangular(255, dna_copy[shape_index][3]))

elif roulette < 0.5:
dna_copy[shape_index][4] = int(random.triangular(255, dna_copy[shape_index][4]))

elif roulette < 0.75:
dna_copy[shape_index][5] = int(random.triangular(255, dna_copy[shape_index][5]))

elif roulette < 1.0:
dna_copy[shape_index][6] = int(0.00390625 * random.triangular(255, dna_copy[shape_index][6] * 255))

else:

if roulette < 1.25:
dna_copy[shape_index][0] = (int(random.triangular(width, dna_copy[shape_index][0][0])), int(random.triangular(height, dna_copy[shape_index][0][1])))

elif roulette < 1.5:
dna_copy[shape_index][2] = (int(random.triangular(width, dna_copy[shape_index][3][0])), int(random.triangular(height, dna_copy[shape_index][4][1])))

elif roulette < 1.75:
dna_copy[shape_index][3] = (int(random.triangular(width, dna_copy[shape_index][4][0])), int(random.triangular(height, dna_copy[shape_index][5][1])))

return dna_copy

def fitness(original, new):
fitness = 0

for x in range(0, width):
for y in range(0, height):
r1, g1, b1, a1 = original.getpixel((x, y))
r2, g2, b2, a2 = new.getpixel((x, y))

deltaRed = r1 - r2
deltaGreen = g1 - g2
deltaBlue = b1 - b2
deltaAlpha = a1 - a2

pixelFitness = deltaRed + deltaGreen + deltaBlue + deltaAlpha

fitness += pixelFitness

return fitness

def generate():
mother = random_genome()
best_genome = mother
best_fitness = fitness(optimal, render_daughter(best_genome))


for i in range(generations):
daughter = copy.deepcopy(best_genome)
daughter = mutate(daughter)

daughter_fitness = fitness(optimal, render_daughter(daughter))

if daughter_fitness < best_fitness:
best_genome = daughter
best_fitness = daughter_fitness

if i % 50 == 0:
print i

if i % 1000 == 0:
render_daughter(best_genome).save("iterations/output_" + str(i) + ".png")

if __name__ == "__main__":
generate()

我使用的开始图片:

Mona Lisa

1000代后的输出图像:

Output 1000

5000代后的输出图像:

Output 5000

最佳答案

您正在检查新适应度是否小于当前适应度:

if daughter_fitness < best_fitness:

但是,您计算的适应度可能为负数:

deltaRed = r1 - r2
deltaGreen = g1 - g2
deltaBlue = b1 - b2
deltaAlpha = a1 - a2

pixelFitness = deltaRed + deltaGreen + deltaBlue + deltaAlpha

fitness += pixelFitness

各种delta* 变量可以是负数也可以是正数;您的测试将有利于负增量,增加“最佳”图像的白度(r2g2 等的值越高,适应度越低,图像越白,直到它们都达到 255、255、255。我不知道增加 alpha 是增加还是减少透明度)。

因此,您应该取差异的绝对值:

deltaRed = abs(r1 - r2)
deltaGreen = abs(g1 - g2)
deltaBlue = abs(b1 - b2)
deltaAlpha = abs(a1 - a2)

您还可以考虑平方和或平方和的平方根(基本上,将其变成最小二乘拟合例程):

deltaRed = r1 - r2
deltaGreen = g1 - g2
deltaBlue = b1 - b2
deltaAlpha = a1 - a2

pixelFitness = math.sqrt(deltaRed**2 + deltaGreen**2 + deltaBlue**2 + deltaAlpha**2)

fitness += pixelFitness

最后,我注意到您的程序不适合我。它位于 mutate() 函数的后半部分,在这里您为 x、y 或 z 分配新值,但使用大于 2 的索引。random_genome() 表明您尝试访问颜色值,它们是整数,甚至尝试索引这些值。

这会导致异常,所以我什至不知道如何让这个程序运行。它要么从一开始就没有运行,要么你没有正确地复制粘贴。我已经将其更改为

if roulette < 1.25:
dna_copy[shape_index][0] = (int(random.triangular(
width, dna_copy[shape_index][0][0])), int(
random.triangular(height, dna_copy[shape_index][0][1])))
elif roulette < 1.5:
dna_copy[shape_index][1] = (int(random.triangular(
width, dna_copy[shape_index][1][0])), int(
random.triangular(height, dna_copy[shape_index][1][1])))
elif roulette < 1.75:
dna_copy[shape_index][2] = (int(random.triangular(
width, dna_copy[shape_index][2][0])), int(
random.triangular(height, dna_copy[shape_index][2][1])))

这似乎做你想做的事。

关于python - 遗传算法图像进化的不正确结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25134050/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com