mirror of
https://github.com/Rushilwiz/AI.git
synced 2025-04-03 19:40:16 -04:00
feat: updated to latest after course
This commit is contained in:
parent
5347d0988d
commit
e70c105347
257
Unit 4/crossword/Umaretiya_r_U4_L5.py
Normal file
257
Unit 4/crossword/Umaretiya_r_U4_L5.py
Normal file
|
@ -0,0 +1,257 @@
|
|||
import sys; args = sys.argv[1:]
|
||||
|
||||
# Name: Rushil Umaretiya
|
||||
# Date: 3-18-2021
|
||||
|
||||
import re
|
||||
|
||||
BLOCKCHAR = '#'
|
||||
OPENCHAR = '-'
|
||||
PROTECTEDCHAR = '~'
|
||||
|
||||
def crossword(args):
|
||||
# parse input
|
||||
# args = ['13x13', '32', 'dct20k.txt', 'H1x4#Toe#', 'H9x2#', 'V3x6#', 'H10x0Scintillating', 'V0x5stirrup', 'H4x2##Ordained', 'V0x1Sums', 'V0x12Mah', 'V5x0pew']
|
||||
height, width, block_count, wordlist, words = parse_input(args)
|
||||
|
||||
# initialize board
|
||||
board, width, height, block_count = initialize(width, height, words, block_count)
|
||||
|
||||
print("init board:")
|
||||
display(board, width, height)
|
||||
|
||||
# add blocking chars
|
||||
print("add blocks:")
|
||||
board = add_blocks(board, width, height, block_count)
|
||||
|
||||
if board == None:
|
||||
print('Board is none.')
|
||||
raise Exception(f'Board is none.')
|
||||
|
||||
# display(board, width, height)
|
||||
# remove border
|
||||
board, width, height = finish_board(board, width, height, words)
|
||||
|
||||
#print(f'{block_count} {board.count(BLOCKCHAR)}')
|
||||
print(board.count(BLOCKCHAR))
|
||||
display(board, width, height)
|
||||
|
||||
def parse_input(args):
|
||||
tests = [r'^(\d+)x(\d+)$', r'^\d+$', r'^(H|V)(\d+)x(\d+)(.+)$']
|
||||
height, width, block_count, wordlist, words = 0, 0, 0, '', []
|
||||
|
||||
for arg in args:
|
||||
# if os.path.isfile(arg):
|
||||
# wordlist = arg
|
||||
# else:
|
||||
for i in range(len(tests)):
|
||||
match = re.search(tests[i], arg, re.I)
|
||||
if match == None: continue
|
||||
if i == 0:
|
||||
height = int(match.group(1))
|
||||
width = int(match.group(2))
|
||||
elif i == 1:
|
||||
block_count = int(match.group(0))
|
||||
elif i == 2:
|
||||
words.append((match.group(1).upper(), int(match.group(2)), int(match.group(3)), match.group(4).upper()))
|
||||
return height, width, block_count, wordlist, words
|
||||
|
||||
def initialize(width, height, words, block_count):
|
||||
board = OPENCHAR * height * width
|
||||
for word in words:
|
||||
index = word[1] * width + word[2]
|
||||
for letter in word[3]:
|
||||
new_char = BLOCKCHAR if letter == BLOCKCHAR else PROTECTEDCHAR
|
||||
board = board[:index] + new_char + board[index + 1 :]
|
||||
board = board[:(len(board) - 1) - index] + new_char + board[len(board) - index:]
|
||||
if word[0] == 'H':
|
||||
index += 1
|
||||
else:
|
||||
index += width
|
||||
block_count -= board.count(BLOCKCHAR)
|
||||
display(board, width, height)
|
||||
board = add_border(board, width, height)
|
||||
width += 2
|
||||
height += 2
|
||||
# display(board, width, height)
|
||||
board = protect(board, width, height)
|
||||
# display(board, width, height)
|
||||
return board, width, height, block_count
|
||||
|
||||
def protect(board, width, height):
|
||||
right_test = rf'({BLOCKCHAR}(\w|{PROTECTEDCHAR})(\w|{PROTECTEDCHAR})){OPENCHAR}'
|
||||
left_test = rf'{OPENCHAR}((\w|{PROTECTEDCHAR})(\w|{PROTECTEDCHAR}){BLOCKCHAR})'
|
||||
|
||||
for i in range(2):
|
||||
board = re.sub(left_test, rf'{PROTECTEDCHAR}\1', board)
|
||||
board = re.sub(right_test, rf'\1{PROTECTEDCHAR}', board)
|
||||
board = transpose(board, width)
|
||||
width, height = height, width
|
||||
# display(board, width, height)
|
||||
|
||||
return board
|
||||
|
||||
def transpose(board, width):
|
||||
return ''.join([board[col::width] for col in range(width)])
|
||||
|
||||
def add_border(board, width, height):
|
||||
border_board = BLOCKCHAR*(width+3)
|
||||
border_board +=(BLOCKCHAR*2).join([board[p:p+width] for p in range(0,len(board),width)])
|
||||
border_board += BLOCKCHAR*(width+3)
|
||||
return border_board
|
||||
|
||||
def remove_border(board, width, height):
|
||||
no_border = ''
|
||||
for i in range(len(board)):
|
||||
if (width <= i < width * (height - 1)) and ((i + 1) % width != 0) and (i % width != 0):
|
||||
no_border += board[i]
|
||||
return no_border, width - 2, height - 2
|
||||
|
||||
def blocking_heuristic(index, board, width):
|
||||
left = 0
|
||||
temp = index
|
||||
while board[temp] != BLOCKCHAR:
|
||||
left += 1
|
||||
temp += 1
|
||||
right = 0
|
||||
temp = index
|
||||
while board[temp] != BLOCKCHAR:
|
||||
right += 1
|
||||
temp -= 1
|
||||
up = 0
|
||||
temp = index
|
||||
while board[temp] != BLOCKCHAR:
|
||||
up += 1
|
||||
temp += width
|
||||
down = 0
|
||||
temp = index
|
||||
while board[temp] != BLOCKCHAR:
|
||||
down += 1
|
||||
temp -= width
|
||||
return up * down + left * right
|
||||
|
||||
def add_blocks(board, width, height, block_count):
|
||||
if block_count == 0:
|
||||
return board
|
||||
|
||||
if board.count(OPENCHAR) == block_count:
|
||||
return BLOCKCHAR * len(board)
|
||||
|
||||
if block_count % 2 == 1:
|
||||
if width * height % 2 == 1:
|
||||
board = board[: len(board) // 2] + BLOCKCHAR + board[(len(board) // 2) + 1 :]
|
||||
block_count -= 1
|
||||
else:
|
||||
raise Exception("Cannot place an odd number of blockchars on an even sized board.")
|
||||
|
||||
print(board)
|
||||
if re.search(f'#[{PROTECTEDCHAR+OPENCHAR}]{{1,2}}#', board) or re.search(f'#[{PROTECTEDCHAR+OPENCHAR}]{{1,2}}#', transpose(board, width)):
|
||||
|
||||
display(board, width, height)
|
||||
|
||||
for i in range(2):
|
||||
presub = board.count(BLOCKCHAR)
|
||||
board, num = re.subn(f'#([{PROTECTEDCHAR+OPENCHAR}][{PROTECTEDCHAR+OPENCHAR}]#)*', lambda x: '#' * len(x.group()), board)
|
||||
board, num = re.subn(f'#([{PROTECTEDCHAR+OPENCHAR}]#)*', lambda x: '#' * len(x.group()), board)
|
||||
block_count -= board.count(BLOCKCHAR) - presub
|
||||
|
||||
board = transpose(board, width)
|
||||
width, height = height, width
|
||||
|
||||
# print("yes.")
|
||||
display(board, width, height)
|
||||
# print("yes")
|
||||
possible = [i for i in range(len(board)) if board[i] != BLOCKCHAR]
|
||||
fills = {}
|
||||
|
||||
for i in possible:
|
||||
fills[i] = area_fill(board, width, i)
|
||||
|
||||
fill_counts = {}
|
||||
for fill in fills.keys():
|
||||
count = fills[fill].count('?')
|
||||
|
||||
if count not in fill_counts.values():
|
||||
fill_counts[fill] = count
|
||||
|
||||
fill_counts = {key: value for key, value in sorted(fill_counts.items(), key=lambda item: item[1])}
|
||||
for fill in fill_counts:
|
||||
if fill_counts[fill] < (width - 2) * (height - 2) - (board.count(PROTECTEDCHAR) + board.count(OPENCHAR)):
|
||||
board = area_fill(board, width, fill, char=BLOCKCHAR)
|
||||
board = area_fill(board, width, len(board) - 1 - fill, char=BLOCKCHAR)
|
||||
block_count -= fill_counts[fill] * 2
|
||||
break
|
||||
|
||||
options = [i for i in range(len(board)) if board[i] == board[(len(board) - 1) - i] == OPENCHAR]
|
||||
return blocks_backtrack(board, width, height, block_count, options)
|
||||
|
||||
def blocks_backtrack(board, width, height, block_count, options):
|
||||
# print(options)
|
||||
# display(board, width, height)
|
||||
|
||||
if block_count == 0 or len(options) == 0:
|
||||
return board
|
||||
|
||||
for option in sorted(options, key=lambda i: blocking_heuristic(i, board, width)):
|
||||
if is_valid_blocking(board, width, height, option):
|
||||
copy = board[:option] + BLOCKCHAR + board[option + 1 :]
|
||||
copy = copy[: (len(copy) - 1) - option] + BLOCKCHAR + copy[len(copy) - option :]
|
||||
updated_options = [i for i in options if i != option]
|
||||
result = blocks_backtrack(copy, width, height, block_count - 2, updated_options)
|
||||
if result != None: return result
|
||||
|
||||
return None
|
||||
|
||||
def is_valid_blocking(board, width, height, option):
|
||||
if board[option] != OPENCHAR: return False
|
||||
temp = board[:option] + BLOCKCHAR + board[option + 1:]
|
||||
temp = temp[:(len(temp) - 1) - option] + BLOCKCHAR + temp[len(temp) - option :]
|
||||
|
||||
illegalRegex = rf"[{BLOCKCHAR}](.?({PROTECTEDCHAR}|{OPENCHAR})|({PROTECTEDCHAR}|{OPENCHAR}).?)[{BLOCKCHAR}]"
|
||||
if re.search(illegalRegex, temp) != None: return False
|
||||
if re.search(illegalRegex, transpose(temp, width)) != None: return False
|
||||
return True
|
||||
|
||||
def area_fill(board, width, sp, char='?'):
|
||||
dirs = [-1, width, 1, -1 * width]
|
||||
if sp < 0 or sp >= len(board): return board
|
||||
if board[sp] in (OPENCHAR, PROTECTEDCHAR):
|
||||
board = board[0:sp] + char + board[sp+1:]
|
||||
for d in dirs:
|
||||
if d == -1 and sp % width == 0: continue
|
||||
if d == 1 and sp + 1 % width == 0: continue
|
||||
board = area_fill(board, width, sp + d, char)
|
||||
return board
|
||||
|
||||
def finish_board(board, width, height, words):
|
||||
# remove border
|
||||
board, width, height = remove_border(board, width, height)
|
||||
|
||||
# add words
|
||||
for word in words:
|
||||
index = word[1] * width + word[2]
|
||||
for letter in word[3]:
|
||||
board = board[:index] + letter + board[index + 1 :]
|
||||
if word[0] == 'H':
|
||||
index += 1
|
||||
else:
|
||||
index += width
|
||||
|
||||
# replace protected with open
|
||||
board = re.sub(PROTECTEDCHAR, OPENCHAR, board)
|
||||
|
||||
return board, width, height
|
||||
|
||||
def display(board, width, height):
|
||||
for i in range(height):
|
||||
line = ""
|
||||
for letter in range(width):
|
||||
line += (board[(i * width) + letter] + " ")
|
||||
print(line)
|
||||
print()
|
||||
|
||||
def main():
|
||||
crossword(args)
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
116
Unit 5/Umaretiya_r_U5_L1.py
Normal file
116
Unit 5/Umaretiya_r_U5_L1.py
Normal file
|
@ -0,0 +1,116 @@
|
|||
from pomegranate import *
|
||||
|
||||
# Pop Quiz
|
||||
|
||||
# Graduated (G) Node
|
||||
Graduated = DiscreteDistribution({'graduated':0.9, 'no-graduated':0.1})
|
||||
|
||||
# Offer Child Nodes
|
||||
Offer1 = ConditionalProbabilityTable([
|
||||
['graduated', 'offer', 0.5],
|
||||
['graduated', 'no-offer', 0.5],
|
||||
['no-graduated', 'offer', 0.05],
|
||||
['no-graduated', 'no-offer', 0.95]], [Graduated])
|
||||
|
||||
Offer2 = ConditionalProbabilityTable([
|
||||
['graduated', 'offer', 0.75],
|
||||
['graduated', 'no-offer', 0.25],
|
||||
['no-graduated', 'offer', 0.25],
|
||||
['no-graduated', 'no-offer', 0.75]], [Graduated])
|
||||
|
||||
# Setting up states for each node
|
||||
s_graduated = State(Graduated, 'graduated-offer')
|
||||
s_offer_1 = State(Offer1, 'offer_1')
|
||||
s_offer_2 = State(Offer2, 'offer_2')
|
||||
|
||||
# Creating Bayesian Network
|
||||
model = BayesianNetwork('graduated-offer')
|
||||
|
||||
# Adding nodes to network
|
||||
model.add_states(s_graduated, s_offer_1, s_offer_2)
|
||||
|
||||
# Creating edges
|
||||
model.add_transition(s_graduated, s_offer_1)
|
||||
model.add_transition(s_graduated, s_offer_2)
|
||||
|
||||
model.bake() # finalize the topology of the model
|
||||
|
||||
print()
|
||||
print('Pop Quiz:')
|
||||
print('The number of nodes:', model.node_count())
|
||||
print('The number of edges:', model.edge_count())
|
||||
|
||||
# predict_proba(Given factors)
|
||||
# P(o2 | g, ~o1)
|
||||
print('P(o2 | g, ~o1): ', model.predict_proba({'graduated-offer': 'graduated', 'offer_1': 'no-offer'})[2].parameters[0]['offer'])
|
||||
|
||||
# predict_proba(Given factors)
|
||||
# P(g | o1, o2)
|
||||
print('P(g | o1, o2): ', model.predict_proba({'offer_1': 'offer', 'offer_2': 'offer'})[0].parameters[0]['graduated'])
|
||||
|
||||
# predict_proba(Given factors)
|
||||
# P(g | ~o1, o2)
|
||||
print('P(g | ~o1, o2): ', model.predict_proba({'offer_1': 'no-offer', 'offer_2': 'offer'})[0].parameters[0]['graduated'])
|
||||
|
||||
# predict_proba(Given factors)
|
||||
# P(g | ~o1, ~o2)
|
||||
print('P(g | ~o1, ~o2): ', model.predict_proba({'offer_1': 'no-offer', 'offer_2': 'no-offer'})[0].parameters[0]['graduated'])
|
||||
|
||||
# predict_proba(Given factors)
|
||||
# P(o2 | o1)
|
||||
print('P(o2 | o1): ', model.predict_proba({'offer_1': 'offer'})[2].parameters[0]['offer'])
|
||||
|
||||
# Example 5, Day 2 Note
|
||||
|
||||
# Happiness Factors
|
||||
Sunny = DiscreteDistribution({'sunny':0.7, 'not-sunny':0.3})
|
||||
Raise = DiscreteDistribution({'raise': 0.01, 'no-raise': 0.99})
|
||||
|
||||
# Happiness Conditional Probability
|
||||
Happiness = ConditionalProbabilityTable([
|
||||
['sunny', 'raise', 'happy', 1],
|
||||
['sunny', 'raise', 'not-happy', 0],
|
||||
['sunny', 'no-raise', 'happy', 0.7],
|
||||
['sunny', 'no-raise', 'not-happy', 0.3],
|
||||
['not-sunny', 'raise', 'happy', 0.9],
|
||||
['not-sunny', 'raise', 'not-happy', 0.1],
|
||||
['not-sunny', 'no-raise', 'happy', 0.1],
|
||||
['not-sunny', 'no-raise', 'not-happy', 0.9]], [Sunny, Raise])
|
||||
|
||||
# Setting up states for each node
|
||||
s_sunny = State(Sunny, 'is-sunny')
|
||||
s_raise = State(Raise, 'got-raise')
|
||||
s_happiness = State(Happiness, 'happiness')
|
||||
|
||||
# Creating Bayesian Network
|
||||
model = BayesianNetwork('happiness-network')
|
||||
|
||||
# Adding nodes to network
|
||||
model.add_states(s_sunny, s_raise, s_happiness)
|
||||
|
||||
# Creating edges
|
||||
model.add_transition(s_sunny, s_happiness)
|
||||
model.add_transition(s_raise, s_happiness)
|
||||
|
||||
model.bake() # finalize the topology of the model
|
||||
|
||||
print()
|
||||
print('Day 2 Note, Example 3:')
|
||||
print('The number of nodes:', model.node_count())
|
||||
print('The number of edges:', model.edge_count())
|
||||
|
||||
# predict_proba(Given factors)
|
||||
# P(r | s)
|
||||
print('P(r | s): ', model.predict_proba({'is-sunny': 'sunny'})[1].parameters[0]['raise'])
|
||||
|
||||
# predict_proba(Given factors)
|
||||
# P(r | h, s)
|
||||
print('P(r | h, s): ', model.predict_proba({'is-sunny': 'sunny', 'happiness': 'happy'})[1].parameters[0]['raise'])
|
||||
|
||||
# predict_proba(Given factors)
|
||||
# P(r | h)
|
||||
print('P(r | h): ', model.predict_proba({'happiness': 'happy'})[1].parameters[0]['raise'])
|
||||
|
||||
# predict_proba(Given factors)
|
||||
# P(r | h, ~s)
|
||||
print('P(r | h, ~s): ', model.predict_proba({'is-sunny': 'not-sunny', 'happiness': 'happy'})[1].parameters[0]['raise'])
|
132
Unit 6/Kanchinadam_n_U6_L2.py
Normal file
132
Unit 6/Kanchinadam_n_U6_L2.py
Normal file
|
@ -0,0 +1,132 @@
|
|||
import sys; args = sys.argv[1:]
|
||||
import math, random
|
||||
|
||||
# Sample input: x_gate.txt
|
||||
|
||||
|
||||
# t_funct is symbol of transfer functions: 'T1', 'T2', 'T3', or 'T4'
|
||||
# input is a list of input (summation) values of the current layer
|
||||
# returns a list of output values of the current layer
|
||||
def transfer(t_funct, input):
|
||||
if t_funct == 'T3': return [1 / (1 + math.e**-x) for x in input]
|
||||
elif t_funct == 'T4': return [-1+2/(1+math.e**-x) for x in input]
|
||||
elif t_funct == 'T2': return [x if x > 0 else 0 for x in input]
|
||||
else: return [x for x in input]
|
||||
|
||||
def
|
||||
|
||||
# returns a list of dot_product result. the len of the list == stage
|
||||
# dot_product([x1, x2, x3], [w11, w21, w31, w12, w22, w32], 2) => [x1*w11 + x2*w21 + x3*w31, x1*w12, x2*w22, x3*w32]
|
||||
def dot_product(input, weights, stage):
|
||||
return [sum([input[x]*weights[x+s*len(input)] for x in range(len(input))]) for s in range(stage)]
|
||||
|
||||
# Complete the whole forward feeding for one input(training) set
|
||||
# return updated x_vals and error of the one forward feeding
|
||||
def ff(ts, xv, weights, t_funct):
|
||||
|
||||
''' ff coding goes here '''
|
||||
for i in range(len(weights) - 1):
|
||||
for j in range(len(xv[i + 1])):
|
||||
xv[i + 1][j] = 0
|
||||
for j in range(len(weights[i])):
|
||||
xv[i + 1][j // len(xv[i])] += xv[i][j % len(xv[i])] * weights[i][j]
|
||||
xv[i + 1] = transfer(t_funct, xv[i + 1])
|
||||
for i in range(len(weights[-1])):
|
||||
xv[-1][i] = xv[-2][i] * weights[-1][i]
|
||||
err = (ts[-1] - xv[-1][0])**2 / 2
|
||||
return xv, err
|
||||
|
||||
# Complete the back propagation with one training set and corresponding x_vals and weights
|
||||
# update E_vals (ev) and negative_grad, and then return those two lists
|
||||
def bp(ts, xv, weights, ev, negative_grad):
|
||||
|
||||
''' bp coding goes here '''
|
||||
ev[-1][0] = ts[-1] - xv[-1][0]
|
||||
for i in range(len(weights) - 1, -1, -1):
|
||||
for j in range(len(negative_grad[i])):
|
||||
negative_grad[i][j] = xv[i][j % len(xv[i])] * ev[i + 1][j // len(ev[i])]
|
||||
if i != 0:
|
||||
for j in range(len(ev[i])):
|
||||
ev[i][j] = 0
|
||||
for k in range(len(ev[i + 1])):
|
||||
ev[i][j] += ev[i + 1][k] * weights[i][k * len(ev[i]) + j]
|
||||
ev[i][j] *= xv[i][j] * (1 - xv[i][j])
|
||||
return ev, negative_grad
|
||||
|
||||
# update all weights and return the new weights
|
||||
# Challenge: one line solution is possible
|
||||
def update_weights(weights, negative_grad, alpha):
|
||||
|
||||
''' update weights (modify NN) code goes here '''
|
||||
for i in range(len(weights)):
|
||||
for j in range(len(weights[i])):
|
||||
weights[i][j] += negative_grad[i][j] * alpha
|
||||
return weights
|
||||
|
||||
def main():
|
||||
file = sys.argv[1] # only one input (a txt file with training set data)
|
||||
#if not os.path.isfile(file): exit("Error: training set is not given")
|
||||
t_funct = 'T3' # we default the transfer(activation) function as 1 / (1 + math.e**(-x))
|
||||
training_set = [[float(x) for x in line.split() if x != '=>'] for line in open(file, 'r').read().splitlines() if line.strip() != '']
|
||||
#print (training_set) #[[1.0, -1.0, 1.0], [-1.0, 1.0, 1.0], [1.0, 1.0, 1.0], [-1.0, -1.0, 1.0], [0.0, 0.0, 0.0]]
|
||||
layer_counts = [len(training_set[0]), 2, 1, 1]
|
||||
print ('layer counts', layer_counts) # This is the first output. [3, 2, 1, 1] with teh given x_gate.txt
|
||||
|
||||
''' build NN: x nodes and weights '''
|
||||
x_vals = [[temp[0:len(temp)-1]] for temp in training_set] # x_vals starts with first input values
|
||||
#print (x_vals) # [[[1.0, -1.0]], [[-1.0, 1.0]], [[1.0, 1.0]], [[-1.0, -1.0]], [[0.0, 0.0]]]
|
||||
# make the x value structure of the NN by putting bias and initial value 0s.
|
||||
for i in range(len(training_set)):
|
||||
for j in range(len(layer_counts)):
|
||||
if j == 0: x_vals[i][j].append(1.0)
|
||||
else: x_vals[i].append([0 for temp in range(layer_counts[j])])
|
||||
#print (x_vals) # [[[1.0, -1.0, 1.0], [0, 0], [0], [0]], [[-1.0, 1.0, 1.0], [0, 0], [0], [0]], ...
|
||||
|
||||
# by using the layer counts, set initial weights [3, 2, 1, 1] => 3*2 + 2*1 + 1*1: Total 6, 2, and 1 weights are needed
|
||||
weights = [[round(random.uniform(-2.0, 2.0), 2) for j in range(layer_counts[i]*layer_counts[i+1])] for i in range(len(layer_counts)-1)]
|
||||
weights = [[1.35, -1.34, -1.66, -0.55, -0.9, -0.58, -1.0, 1.78], [-1.08, -0.7], [-0.6]] #Example 2
|
||||
# print (weights) #[[2.0274715389784507e-05, -3.9375970265443985, 2.4827119599531016, 0.00014994269071843774, -3.6634876683142332, -1.9655046461270405]
|
||||
#[-3.7349985848630634, 3.5846029322774617]
|
||||
#[2.98900741942973]]
|
||||
|
||||
# build the structure of BP NN: E nodes and negative_gradients
|
||||
E_vals = [[*i] for i in x_vals] #copy elements from x_vals, E_vals has the same structures with x_vals
|
||||
negative_grad = [[*i] for i in weights] #copy elements from weights, negative gradients has the same structures with weights
|
||||
errors = [10]*len(training_set) # Whenever FF is done once, error will be updated. Start with 10 (a big num)
|
||||
count = 1 # count how many times you trained the network, this can be used for index calc or for decision making of 'restart'
|
||||
alpha = 0.3
|
||||
|
||||
# calculate the initail error sum. After each forward feeding (# of training sets), calculate the error and store at error list
|
||||
err = sum(errors)
|
||||
while err >= 0.01:
|
||||
weights = [[round(random.uniform(-2.0, 2.0), 2) for j in range(layer_counts[i]*layer_counts[i+1])] for i in range(len(layer_counts)-1)]
|
||||
count = 0
|
||||
while err >= 0.01:
|
||||
for i in range(len(x_vals)):
|
||||
x_vals[i], errors[i] = ff(training_set[i], x_vals[i], weights, t_funct)
|
||||
err = sum(errors)
|
||||
if count >= 2000 and err > 0.05:
|
||||
break
|
||||
for i in range(len(E_vals)):
|
||||
bp(training_set[i], x_vals[i], weights, E_vals[i], negative_grad)
|
||||
update_weights(weights, negative_grad, alpha)
|
||||
count += 1
|
||||
|
||||
'''
|
||||
while err is too big, reset all weights as random values and re-calculate the error sum.
|
||||
|
||||
'''
|
||||
|
||||
'''
|
||||
while err does not reach to the goal and count is not too big,
|
||||
update x_vals and errors by calling ff()
|
||||
whenever all training sets are forward fed,
|
||||
check error sum and change alpha or reset weights if it's needed
|
||||
update E_vals and negative_grad by calling bp()
|
||||
update weights
|
||||
count++
|
||||
'''
|
||||
# print final weights of the working NN
|
||||
print ('weights:')
|
||||
for w in weights: print (w)
|
||||
if __name__ == '__main__': main()
|
75
Unit 6/Umaretiya_r_U6_L1.py
Normal file
75
Unit 6/Umaretiya_r_U6_L1.py
Normal file
|
@ -0,0 +1,75 @@
|
|||
import sys; args = sys.argv[1:]
|
||||
|
||||
# Name: Rushil Umaretiya
|
||||
# Date: 4-29-2021
|
||||
|
||||
import os, math
|
||||
|
||||
def transfer(t_funct, input_val):
|
||||
x = sum(input_val)
|
||||
functions = {
|
||||
'T1': x,
|
||||
'T2': 0 if x <= 0 else x,
|
||||
'T3': 1 / (1 + math.e ** -x),
|
||||
'T4': -1 + 2/(1+math.e**-x)
|
||||
}
|
||||
if t_funct in functions:
|
||||
return functions[t_funct]
|
||||
raise Exception('That is not a valid transfer function.')
|
||||
|
||||
def dot_product(input_vals, weights, layer):
|
||||
return [[input_vals[weight] * weights[layer][cell_num][weight] for weight in range(len(weights[layer][cell_num]))] for cell_num in range(len(weights[layer]))]
|
||||
|
||||
def evaluate(file, input_vals, t_funct):
|
||||
with open(file, 'r') as weight_file:
|
||||
# had to do this because ai grader is weird
|
||||
raw_lines = [[float(weight) for weight in layer.split()] for layer in weight_file.read().split('\n')]
|
||||
lines = [line for line in raw_lines if len(line) != 0]
|
||||
|
||||
|
||||
weights = []
|
||||
|
||||
for i in range(len(lines)):
|
||||
if (i == 0):
|
||||
cells = len(input_vals)
|
||||
else:
|
||||
cells = len(weights[i - 1])
|
||||
|
||||
cell_weight = []
|
||||
|
||||
for cell in range(len(lines[i]) // cells):
|
||||
weight = lines[i][cell * cells : (cell + 1) * cells]
|
||||
cell_weight.append(weight)
|
||||
|
||||
weights.append(cell_weight)
|
||||
|
||||
layer = 0
|
||||
while (layer < len(weights) - 1):
|
||||
weighted_input = dot_product(input_vals, weights, layer)
|
||||
input_vals = []
|
||||
for input_val in weighted_input:
|
||||
input_vals.append(transfer(t_funct, input_val))
|
||||
layer += 1
|
||||
|
||||
output = []
|
||||
|
||||
for i in range(len(weights[layer][0])):
|
||||
output.append(weights[layer][0][i] * input_vals[i])
|
||||
|
||||
return output
|
||||
|
||||
def main():
|
||||
args = sys.argv[1:]
|
||||
file, inputs, t_funct, transfer_found = '', [], 'T1', False
|
||||
for arg in args:
|
||||
if os.path.isfile(arg):
|
||||
file = arg
|
||||
elif not transfer_found:
|
||||
t_funct, transfer_found = arg, True
|
||||
else:
|
||||
inputs.append(float(arg))
|
||||
if len(file)==0: exit("Error: Weights file is not given")
|
||||
li = (evaluate(file, inputs, t_funct))
|
||||
for x in li:
|
||||
print (x, end=' ')
|
||||
if __name__ == '__main__': main()
|
132
Unit 6/Umaretiya_r_U6_L2.py
Normal file
132
Unit 6/Umaretiya_r_U6_L2.py
Normal file
|
@ -0,0 +1,132 @@
|
|||
import sys; args = sys.argv[1:]
|
||||
import math, random
|
||||
|
||||
# Sample input: x_gate.txt
|
||||
|
||||
|
||||
# t_funct is symbol of transfer functions: 'T1', 'T2', 'T3', or 'T4'
|
||||
# input is a list of input (summation) values of the current layer
|
||||
# returns a list of output values of the current layer
|
||||
def transfer(t_funct, input):
|
||||
if t_funct == 'T3': return [1 / (1 + math.e**-x) for x in input]
|
||||
elif t_funct == 'T4': return [-1+2/(1+math.e**-x) for x in input]
|
||||
elif t_funct == 'T2': return [x if x > 0 else 0 for x in input]
|
||||
else: return [x for x in input]
|
||||
|
||||
def
|
||||
|
||||
# returns a list of dot_product result. the len of the list == stage
|
||||
# dot_product([x1, x2, x3], [w11, w21, w31, w12, w22, w32], 2) => [x1*w11 + x2*w21 + x3*w31, x1*w12, x2*w22, x3*w32]
|
||||
def dot_product(input, weights, stage):
|
||||
return [sum([input[x]*weights[x+s*len(input)] for x in range(len(input))]) for s in range(stage)]
|
||||
|
||||
# Complete the whole forward feeding for one input(training) set
|
||||
# return updated x_vals and error of the one forward feeding
|
||||
def ff(ts, xv, weights, t_funct):
|
||||
|
||||
''' ff coding goes here '''
|
||||
for i in range(len(weights) - 1):
|
||||
for j in range(len(xv[i + 1])):
|
||||
xv[i + 1][j] = 0
|
||||
for j in range(len(weights[i])):
|
||||
xv[i + 1][j // len(xv[i])] += xv[i][j % len(xv[i])] * weights[i][j]
|
||||
xv[i + 1] = transfer(t_funct, xv[i + 1])
|
||||
for i in range(len(weights[-1])):
|
||||
xv[-1][i] = xv[-2][i] * weights[-1][i]
|
||||
err = (ts[-1] - xv[-1][0])**2 / 2
|
||||
return xv, err
|
||||
|
||||
# Complete the back propagation with one training set and corresponding x_vals and weights
|
||||
# update E_vals (ev) and negative_grad, and then return those two lists
|
||||
def bp(ts, xv, weights, ev, negative_grad):
|
||||
|
||||
''' bp coding goes here '''
|
||||
ev[-1][0] = ts[-1] - xv[-1][0]
|
||||
for i in range(len(weights) - 1, -1, -1):
|
||||
for j in range(len(negative_grad[i])):
|
||||
negative_grad[i][j] = xv[i][j % len(xv[i])] * ev[i + 1][j // len(ev[i])]
|
||||
if i != 0:
|
||||
for j in range(len(ev[i])):
|
||||
ev[i][j] = 0
|
||||
for k in range(len(ev[i + 1])):
|
||||
ev[i][j] += ev[i + 1][k] * weights[i][k * len(ev[i]) + j]
|
||||
ev[i][j] *= xv[i][j] * (1 - xv[i][j])
|
||||
return ev, negative_grad
|
||||
|
||||
# update all weights and return the new weights
|
||||
# Challenge: one line solution is possible
|
||||
def update_weights(weights, negative_grad, alpha):
|
||||
|
||||
''' update weights (modify NN) code goes here '''
|
||||
for i in range(len(weights)):
|
||||
for j in range(len(weights[i])):
|
||||
weights[i][j] += negative_grad[i][j] * alpha
|
||||
return weights
|
||||
|
||||
def main():
|
||||
file = sys.argv[1] # only one input (a txt file with training set data)
|
||||
#if not os.path.isfile(file): exit("Error: training set is not given")
|
||||
t_funct = 'T3' # we default the transfer(activation) function as 1 / (1 + math.e**(-x))
|
||||
training_set = [[float(x) for x in line.split() if x != '=>'] for line in open(file, 'r').read().splitlines() if line.strip() != '']
|
||||
#print (training_set) #[[1.0, -1.0, 1.0], [-1.0, 1.0, 1.0], [1.0, 1.0, 1.0], [-1.0, -1.0, 1.0], [0.0, 0.0, 0.0]]
|
||||
layer_counts = [len(training_set[0]), 2, 1, 1]
|
||||
print ('layer counts', layer_counts) # This is the first output. [3, 2, 1, 1] with teh given x_gate.txt
|
||||
|
||||
''' build NN: x nodes and weights '''
|
||||
x_vals = [[temp[0:len(temp)-1]] for temp in training_set] # x_vals starts with first input values
|
||||
#print (x_vals) # [[[1.0, -1.0]], [[-1.0, 1.0]], [[1.0, 1.0]], [[-1.0, -1.0]], [[0.0, 0.0]]]
|
||||
# make the x value structure of the NN by putting bias and initial value 0s.
|
||||
for i in range(len(training_set)):
|
||||
for j in range(len(layer_counts)):
|
||||
if j == 0: x_vals[i][j].append(1.0)
|
||||
else: x_vals[i].append([0 for temp in range(layer_counts[j])])
|
||||
#print (x_vals) # [[[1.0, -1.0, 1.0], [0, 0], [0], [0]], [[-1.0, 1.0, 1.0], [0, 0], [0], [0]], ...
|
||||
|
||||
# by using the layer counts, set initial weights [3, 2, 1, 1] => 3*2 + 2*1 + 1*1: Total 6, 2, and 1 weights are needed
|
||||
weights = [[round(random.uniform(-2.0, 2.0), 2) for j in range(layer_counts[i]*layer_counts[i+1])] for i in range(len(layer_counts)-1)]
|
||||
weights = [[1.35, -1.34, -1.66, -0.55, -0.9, -0.58, -1.0, 1.78], [-1.08, -0.7], [-0.6]] #Example 2
|
||||
# print (weights) #[[2.0274715389784507e-05, -3.9375970265443985, 2.4827119599531016, 0.00014994269071843774, -3.6634876683142332, -1.9655046461270405]
|
||||
#[-3.7349985848630634, 3.5846029322774617]
|
||||
#[2.98900741942973]]
|
||||
|
||||
# build the structure of BP NN: E nodes and negative_gradients
|
||||
E_vals = [[*i] for i in x_vals] #copy elements from x_vals, E_vals has the same structures with x_vals
|
||||
negative_grad = [[*i] for i in weights] #copy elements from weights, negative gradients has the same structures with weights
|
||||
errors = [10]*len(training_set) # Whenever FF is done once, error will be updated. Start with 10 (a big num)
|
||||
count = 1 # count how many times you trained the network, this can be used for index calc or for decision making of 'restart'
|
||||
alpha = 0.3
|
||||
|
||||
# calculate the initail error sum. After each forward feeding (# of training sets), calculate the error and store at error list
|
||||
err = sum(errors)
|
||||
while err >= 0.01:
|
||||
weights = [[round(random.uniform(-2.0, 2.0), 2) for j in range(layer_counts[i]*layer_counts[i+1])] for i in range(len(layer_counts)-1)]
|
||||
count = 0
|
||||
while err >= 0.01:
|
||||
for i in range(len(x_vals)):
|
||||
x_vals[i], errors[i] = ff(training_set[i], x_vals[i], weights, t_funct)
|
||||
err = sum(errors)
|
||||
if count >= 2000 and err > 0.05:
|
||||
break
|
||||
for i in range(len(E_vals)):
|
||||
bp(training_set[i], x_vals[i], weights, E_vals[i], negative_grad)
|
||||
update_weights(weights, negative_grad, alpha)
|
||||
count += 1
|
||||
|
||||
'''
|
||||
while err is too big, reset all weights as random values and re-calculate the error sum.
|
||||
|
||||
'''
|
||||
|
||||
'''
|
||||
while err does not reach to the goal and count is not too big,
|
||||
update x_vals and errors by calling ff()
|
||||
whenever all training sets are forward fed,
|
||||
check error sum and change alpha or reset weights if it's needed
|
||||
update E_vals and negative_grad by calling bp()
|
||||
update weights
|
||||
count++
|
||||
'''
|
||||
# print final weights of the working NN
|
||||
print ('weights:')
|
||||
for w in weights: print (w)
|
||||
if __name__ == '__main__': main()
|
3
Unit 6/weights.txt
Normal file
3
Unit 6/weights.txt
Normal file
|
@ -0,0 +1,3 @@
|
|||
5 8 2 0 1 2 2 2 3 7 5 4 4 3 2
|
||||
0 1 7 5 4 3
|
||||
0.5 -1
|
5
Unit 6/x_gate.txt
Normal file
5
Unit 6/x_gate.txt
Normal file
|
@ -0,0 +1,5 @@
|
|||
1 -1 => 1
|
||||
-1 1 => 1
|
||||
1 1 => 1
|
||||
-1 -1 => 1
|
||||
0 0 => 0
|
4
Unit 6/x_gate_2.txt
Normal file
4
Unit 6/x_gate_2.txt
Normal file
|
@ -0,0 +1,4 @@
|
|||
0 1 => 0
|
||||
1 0 => 0
|
||||
1 1 => 1
|
||||
0 0 => 0
|
139
Unit 7/Kim_k_U7_L1.py
Normal file
139
Unit 7/Kim_k_U7_L1.py
Normal file
|
@ -0,0 +1,139 @@
|
|||
''' Test cases:
|
||||
6 https://cf.geekdo-images.com/imagepage/img/5lvEWGGTqWDFmJq_MaZvVD3sPuM=/fit-in/900x600/filters:no_upscale()/pic260745.jpg
|
||||
10 cute_dog.jpg
|
||||
6 turtle.jpg
|
||||
'''
|
||||
import PIL
|
||||
from PIL import Image;
|
||||
import urllib.request
|
||||
import io, sys, os, random
|
||||
|
||||
|
||||
def choose_random_means(k, img, pix):
|
||||
means = []
|
||||
for i in range(k):
|
||||
x = (int)(random.uniform(0, img.size[0]-1))
|
||||
y = (int)(random.uniform(0, img.size[1]-1))
|
||||
means.append(pix[x,y])
|
||||
return means
|
||||
|
||||
# goal test: no hopping
|
||||
def check_move_count(mc):
|
||||
for x in mc:
|
||||
if x != 0: return False
|
||||
return True
|
||||
|
||||
# calculate distance with the current color with each mean
|
||||
# return the index of means
|
||||
def dist(col, means):
|
||||
minIndex, dist_sum = 0, 255**2+255**2+255**2
|
||||
for i in range(len(means)):
|
||||
dist_k = ((means[i][0]-col[0]) ** 2 + (means[i][1]-col[1])**2 + (means[i][2]-col[2])**2) ** 0.5
|
||||
if dist_k < dist_sum:
|
||||
minIndex = i
|
||||
dist_sum = dist_k
|
||||
return minIndex
|
||||
|
||||
def clustering(img, pix, rgb, cb, mc, means, count):
|
||||
temp_pb, temp_mc, temp_m, temp_cb = [[] for x in means], [], [], [0 for x in range(len(means))]
|
||||
for tup in rgb:
|
||||
temp_cb[dist(tup, means)] += 1
|
||||
temp_pb[dist(tup, means)].append(tup)
|
||||
|
||||
# for i in range(img.size[0]):
|
||||
# for j in range(img.size[1]):
|
||||
# temp_cb[dist(pix[i, j], means)] += 1
|
||||
# temp_pb[dist(pix[i, j], means)].append(pix[i, j])
|
||||
|
||||
temp_mc = [ (a-b) for a, b in zip(temp_cb, cb)]
|
||||
temp_m = []
|
||||
for li in temp_pb:
|
||||
sum_r, sum_g, sum_b = 0, 0, 0
|
||||
for tup in li:
|
||||
sum_r += tup[0]
|
||||
sum_g += tup[1]
|
||||
sum_b += tup[2]
|
||||
temp_m.append((sum_r / len(li), sum_g / len(li), sum_b / len(li)))
|
||||
|
||||
print ('diff', count, ':', temp_mc)
|
||||
return temp_cb, temp_mc, temp_m
|
||||
|
||||
def update_picture(img, pix, means):
|
||||
region_dict = {}
|
||||
for x in means:
|
||||
region_dict[x] = 0
|
||||
for i in range(img.size[0]):
|
||||
for j in range(img.size[1]):
|
||||
pix[i, j] = tuple((map(int, means[dist(pix[i, j], means)])))
|
||||
|
||||
return pix, region_dict
|
||||
|
||||
def distinct_pix_count(img, pix):
|
||||
cols = {}
|
||||
max_col, max_count = pix[0, 0], 0
|
||||
for i in range(img.size[0]):
|
||||
for j in range(img.size[1]):
|
||||
if pix[i, j] not in cols.keys():
|
||||
cols[pix[i, j]] = 1
|
||||
else:
|
||||
cols[pix[i, j]] += 1
|
||||
for col in cols.keys():
|
||||
if cols[col] > max_count:
|
||||
max_col = col
|
||||
max_count = cols[col]
|
||||
return len(cols.keys()), max_col, max_count, cols.keys()
|
||||
|
||||
def count_regions(img, region_dict, pix, means):
|
||||
region_count = [0 for x in means]
|
||||
visited = set()
|
||||
|
||||
|
||||
return region_count
|
||||
|
||||
|
||||
def main():
|
||||
k = int(sys.argv[1])
|
||||
file = sys.argv[2]
|
||||
if not os.path.isfile(file):
|
||||
file = io.BytesIO(urllib.request.urlopen(file).read())
|
||||
img = Image.open(file)
|
||||
pix = img.load() # pix[0, 0] : (r, g, b)
|
||||
rgb = []
|
||||
print ('Size:', img.size[0], 'x', img.size[1])
|
||||
print ('Pixels:', img.size[0]*img.size[1])
|
||||
d_count, m_col, m_count, rgb = distinct_pix_count(img, pix)
|
||||
print ('Distinct pixel count:', d_count)
|
||||
print ('Most common pixel:', m_col, '=>', m_count)
|
||||
|
||||
count_buckets = [0 for x in range(k)]
|
||||
move_count = [10 for x in range(k)]
|
||||
means = choose_random_means(k, img, pix)
|
||||
print ('random means:', means)
|
||||
count = 1
|
||||
while not check_move_count(move_count):
|
||||
count += 1
|
||||
count_buckets, move_count, means = clustering(img, pix, rgb, count_buckets, move_count, means, count)
|
||||
if count == 2:
|
||||
print ('first means:', means)
|
||||
print ('starting sizes:', count_buckets)
|
||||
pix, region_dict = update_picture(img, pix, means)
|
||||
print ('Final sizes:', count_buckets)
|
||||
print ('Final means:')
|
||||
for i in range(len(means)):
|
||||
print (i+1, ':', means[i], '=>', count_buckets[i])
|
||||
regions = count_regions(img, region_dict, pix, means) # num of area fills
|
||||
print ('Region counts:', regions)
|
||||
img.save('kmeans/2022tkim.png', 'PNG')
|
||||
|
||||
|
||||
'''
|
||||
Distinct regions:
|
||||
1: # of regions of means[0]
|
||||
Final regions:
|
||||
1: # of final regions of means[0] after taking care of step 3
|
||||
Save your file in the subdirectory, kmeans/userid.png
|
||||
'''
|
||||
#img.show()
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
108
Unit 7/Umaretiya_r_U7_L1.py
Normal file
108
Unit 7/Umaretiya_r_U7_L1.py
Normal file
|
@ -0,0 +1,108 @@
|
|||
''' Test cases:
|
||||
6 https://cf.geekdo-images.com/imagepage/img/5lvEWGGTqWDFmJq_MaZvVD3sPuM=/fit-in/900x600/filters:no_upscale()/pic260745.jpg
|
||||
10 cute_dog.jpg
|
||||
6 turtle.jpg
|
||||
'''
|
||||
import PIL
|
||||
from PIL import Image
|
||||
import urllib.request
|
||||
import io, sys, os, random
|
||||
|
||||
def choose_random_means(k, img, pix):
|
||||
return [pix[(int)(random.uniform(0, img.size[0]-1)),(int)(random.uniform(0, img.size[1]-1))] for i in range(k)]
|
||||
|
||||
# goal test: no hopping
|
||||
def check_move_count(mc):
|
||||
for move in mc:
|
||||
if move != 0: return False
|
||||
return True
|
||||
|
||||
# calculate distance with the current color with each mean
|
||||
# return the index of means
|
||||
def dist(col, means):
|
||||
minIndex, dist_sum = 0, 255 ** 2 + 255 ** 2 + 255 ** 2
|
||||
for i in range(len(means)):
|
||||
dist_k = ((means[i][0]-col[0]) ** 2 + (means[i][1]-col[1])**2 + (means[i][2]-col[2])**2) ** 0.5
|
||||
if dist_k < dist_sum:
|
||||
dist_sum = dist_k
|
||||
minIndex = i
|
||||
return minIndex
|
||||
|
||||
def clustering(img, pix, cb, mc, means, count):
|
||||
temp_pb, temp_mc, temp_m = [[] for x in means], [], []
|
||||
temp_cb = [0 for x in range(len(means))]
|
||||
|
||||
for tup in rgb:
|
||||
temp_cb[dist(tup, means)] += 1
|
||||
temp_pb[dist(tup, means)].append(tup)
|
||||
|
||||
temp_mc = [(a - b) for a, b in zip(temp_cb, cb)]
|
||||
for li in temp_pb:
|
||||
sum_r, sum_g, sum_b = 0, 0, 0
|
||||
for tup in li:
|
||||
sum_r += tup[0]
|
||||
sum_g += tup[1]
|
||||
sum_b += tup[2]
|
||||
temp_m.append((sum_r / len(li), sum_g / len(li), sum_b / len(li)))
|
||||
print ('diff', count, ':', temp_mc)
|
||||
return temp_cb, temp_mc, temp_m
|
||||
|
||||
def update_picture(img, pix, means):
|
||||
region_dict = {}
|
||||
return pix, region_dict
|
||||
|
||||
def distinct_pix_count(img, pix):
|
||||
cols = {}
|
||||
max_col, max_count = pix[0, 0], 0
|
||||
return len(cols.keys()), max_col, max_count
|
||||
|
||||
def count_regions(img, region_dict, pix, means):
|
||||
region_count = [0 for x in means]
|
||||
return region_count
|
||||
|
||||
|
||||
def main():
|
||||
k = int(sys.argv[1])
|
||||
file = sys.argv[2]
|
||||
if not os.path.isfile(file):
|
||||
file = io.BytesIO(urllib.request.urlopen(file).read())
|
||||
img = Image.open(file)
|
||||
pix = img.load() # pix[0, 0] : (r, g, b)
|
||||
print ('Size:', img.size[0], 'x', img.size[1])
|
||||
print ('Pixels:', img.size[0]*img.size[1])
|
||||
d_count, m_col, m_count = distinct_pix_count(img, pix)
|
||||
print ('Distinct pixel count:', d_count)
|
||||
print ('Most common pixel:', m_col, '=>', m_count)
|
||||
|
||||
count_buckets = [0 for x in range(k)]
|
||||
move_count = [10 for x in range(k)]
|
||||
means = choose_random_means(k, img, pix)
|
||||
print ('random means:', means)
|
||||
count = 1
|
||||
while not check_move_count(move_count):
|
||||
count += 1
|
||||
count_buckets, move_count, means = clustering(img, pix, count_buckets, move_count, means, count)
|
||||
if count == 2:
|
||||
print ('first means:', means)
|
||||
print ('starting sizes:', count_buckets)
|
||||
pix, region_dict = update_picture(img, pix, means)
|
||||
print ('Final sizes:', count_buckets)
|
||||
print ('Final means:')
|
||||
for i in range(len(means)):
|
||||
print (i+1, ':', means[i], '=>', count_buckets[i])
|
||||
regions = count_regions(img, region_dict, pix, means) # num of area fills
|
||||
print ('Region counts:', regions)
|
||||
img.save('output.png', 'PNG')
|
||||
|
||||
|
||||
'''
|
||||
Distinct regions:
|
||||
1: # of regions of means[0]
|
||||
Final regions:
|
||||
1: # of final regions of means[0] after taking care of step 3
|
||||
Save your file in the subdirectory, kmeans/userid.png
|
||||
'''
|
||||
img.show()
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
BIN
Unit 7/cute_dog.jpg
Normal file
BIN
Unit 7/cute_dog.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 5.0 KiB |
BIN
Unit 7/output.png
Normal file
BIN
Unit 7/output.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 52 KiB |
BIN
Unit 7/turtle.jpg
Normal file
BIN
Unit 7/turtle.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 6.0 KiB |
Loading…
Reference in New Issue
Block a user