Скачиваний:
0
Добавлен:
13.05.2026
Размер:
7.14 Кб
Скачать
import os
import skimage
import numpy as np
import matplotlib.pyplot as plt
from scipy.optimize import minimize
from threading import Thread
import time

#Создание класса-наследника класса Thread с возвращением элементов
class ThreadRV(Thread):

    def __init__(self, group=None, target=None, name=None,
        args=(), kwargs={}, Verbose=None):
        Thread.__init__(self, group, target, name, args, kwargs)
        self._return = None

    def run(self):
        if self._target is not None:
            self._return = self._target(*self._args, ** self._kwargs)

    def result(self):
        return self._return

#Функция вызова потоков
def thrd_call(trg, argnt1, argnt2, a):
    thread1 = ThreadRV(target=trg, args =argnt1)
    thread2 = ThreadRV(target=trg, args =argnt2)
    thread1.start()
    thread2.start()
    if a == False:
        thread2.join()
        thread1.join()
    elif a == True:
        thread1.join()
        thread2.join()
        return (thread1.result(), thread2.result())

#Функция считывания названий файлов
def f_name(s):
    lt = os.listdir(s)
    return lt

#Функция создания списков изображений
def img_read(ls, path):
    array = []
    for i in ls:
        array.append(np.array(skimage.io.imread(f'{path}/{i}')))
    return array

#Функция «спрямления» изображений
def img_flatten(ls):
	for i in ls:
		i.shape = (len(i)*len(i[0])*3)
		i = i.T

#Функция извлечения части из массива
def arr_cut(array, left_border, right_border):
    array_cut = array[left_border:right_border]
    return array_cut

#Функция нормирования параметров
def norm(arr,mn,st):
	for i in range(len(arr)):
		arr[i] = (arr[i] - mn[i])/st[i]

#Функция обучения гипотезы
def Learn(th, x, y, l):
    ##Функции вычисления значений гипотезы
    def h(th):
        z = x@th
        z[z<-30] = -30
        z[z>30] = 30
        hypothesis = 1/(1+np.exp(-(z)))
        return hypothesis
    ##Функция вычисления значения функции стоимости
    def J(th):
        summ = np.sum(y.T@np.log(h(th))+\
            (np.subtract(1,y)).T@\
            np.log(np.subtract(1,h(th))))
        return (-1)*summ/len(y)
    ##Функция вычисления значений производных
    def dJ(theta):
        dif = (x.T@(np.subtract(h(th),y)))
        return np.divide(dif, len(y))
    j = minimize(J,th,method='BFGS',jac=dJ)
    l.append(j.fun)
    return j.x

#Функция вычисления значения функции стоимости для кроссвалидации
def Cross(th, x, y, l):
    ##Функции вычисления значений гипотезы
    def h(th):
        z = x@th
        z[z<-30] = -30
        z[z>30] = 30
        hypothesis = 1/(1+np.exp(-(z)))
        return hypothesis
    ##Функция вычисления значения функции стоимости
    def J(th):
        summ = np.sum(y.T@np.log(h(th))+\
            (np.subtract(1,y)).T@\
            np.log(np.subtract(1,h(th))))
        return (-1)*summ/len(y)
    l.append(J(th))

#Очистка окна консоли
os.system('cls')

#Запуск таймера
t1 = time.perf_counter_ns()

#Создание списков названий файлов в папках
trees_list, no_trees_list = thrd_call(f_name,\
    ("Trees",), ("NoTrees",), True)

#Создание списков изображений в папке
trees_img_list, no_trees_img_list = thrd_call(img_read,\
    (trees_list, "Trees"), (no_trees_list, "NoTrees"), True)

#Создание массива изображений
##«Спрямление» массивов изображений
thrd_call(img_flatten, (trees_img_list,),
	(no_trees_img_list,), False)
##Объединение массивов в один
X = np.vstack((np.array(trees_img_list[0:len(trees_img_list)+1]),
	np.array(no_trees_img_list[0:len(no_trees_img_list)+1])))
X = X.astype('float64')

#Метод главных кординат
##Максимальное количество параметров
max_par = 60
##Среднее нормирование
mean = np.mean(X.T, axis=1)
std = np.std(X.T, axis=1)
norm(X.T,mean,std)
##Создание матрицы собственных векторов для ковариационной матрицы
p = os.path.isfile('U_matrix.npy')
if p == True:
    ##Создание матрицы преобразований
    U = np.load('U_matrix.npy')
elif p == False:
    ##Создание ковариционной матрицы
    sigma = np.cov(X.T,bias=True)
    ##Создание матрицы преобразований
    U, S, Vh = np.linalg.svd(sigma)
    np.save('U_matrix.npy', U[::, :max_par:])
    del sigma, S, Vh
X_cmprs = X@U #Компрессия изображений
##Масштабирование
X_cmprs= X_cmprs/255

#Создание матрицы параметров
parameters = np.vstack((X_cmprs[0:2200:],X_cmprs[5200:7400]))
parameters = np.hstack((np.ones((len(parameters),1)\
    ,dtype=np.float16),parameters))

#Создание массива результатов
results = np.hstack((np.ones(len(parameters)//2),\
    np.zeros(len(parameters)//2)))

#Перемешивание массивов параметров и результатов
permutation = np.random.permutation(len(parameters))
parameters = parameters[permutation]
results = results[permutation]

#Разделение на части
##Выделение данных на обучение
par_learn, res_learn = thrd_call(arr_cut,\
    (parameters,0,2200), (results,0,2200), True)
##Выделение данных на кроссвалидацию
par_cross, res_cross = thrd_call(arr_cut,\
    (parameters,2200,4400), (results,2200,4400), True)

#Построение кривых обучения
##Создание массива коэффициентов
theta = np.random.rand(len(par_learn[0]))
##Создание массивов для построения графиков
img_amm = [1]
for i in range(100,len(par_learn)+1,100):
    img_amm.append(i)
J_ln = []
J_cv = []
##Обучение при разных количествах изображений
for i in img_amm:
    tmp = (Learn(theta,par_learn[0:i],res_learn[0:i],J_ln))
    Cross(tmp,par_cross[0:i:],res_cross[0:i:],J_cv)

#Вывод графиков на экран
plt.figure(1)
plt.plot(img_amm,J_ln, label="Кроссвалидация")
plt.plot(img_amm,J_cv, label="Обучение")
plt.legend()

#Вывод времени выполнения программы
print(f'\nTotal program execution time: \
{(time.perf_counter_ns()-t1)/10**9:.5f} seconds.')

plt.show()
Соседние файлы в папке лабы