2020年12月30日 星期三

      Conditional Generative Adversarial Nets

今天細說一下什麼何謂GAN、在此不得不提這號人物、楊立昆、他說了GAN是未來10年耶最好玩的事情、其原文如下:“The most interesting idea in the last 10 years in Machine Learning"。GAN有兩個主件組合而成:分別是生成器(Generato)r和鑑別器(Discriminator)

生成器G需要捕獲數據分佈丶判別器D估計樣本的概率來自訓練數據而不是G

讓我想起一部有名的電影、其中文名叫神鬼交鋒是一部於2002年上映的美國傳記犯罪電影為史蒂芬·史匹柏執導傑夫·納桑森編劇李奧納多·狄卡皮歐、湯姆·漢克斯、克里斯多福·沃肯及馬丁·辛主演。劇情根據1960年代著名詐欺犯法蘭克·威廉·艾巴內爾二世的同名自傳改編少年詐欺犯法蘭克·艾巴內爾(Frank Abagnale,李奧納多·狄卡皮歐飾)在1963年至1967年間,以多種不同方式共騙得400萬美元。他在中學時曾冒充代課老師上法語課成功瞞騙同學和校方一週。當時法蘭克的家庭陷入破產危機並遭國稅局「追殺」。法蘭克為了挽救家庭鋌而走險先後扮民航機飛行員、醫生、律師又利用支票系統的漏洞偽造多張支票並成功入帳。



 GAN其模型圖如下圖:











  上面的模型圖是一個最基本的GAN的方塊圖可以看出GAN中有二個Neural Network需要去Training接下來我就來介紹Discriminator跟Generator這二個神經網路應該要怎麼去訓練。

Discriminator (鑑別器)

鑑別器網路簡單一點說明的就是是一個Neural Network可以分辨偽造出來的圖跟真實的圖沒錯,就是很直觀的,我們把Generator出來的圖標記為0(fake image),然後把真實的圖標記為1,這樣的training data 丟進我們的Discriminator Network做訓練,這就是每一次Discriminator訓練的步驟了,接下來我們來看Generator怎麼做,然後再把二個連結再一起。

Generator Network (生成器網路)

生成器網路的概念也很簡單,就是要訓練出一個Neural Network可以讓Discriminator分辨出來的結果越接近真實(1)的結果越好,我畫了以下的圖來理解生成器網路的訓練方式。

沒錯,就是很直觀的,我們把Generator出來的圖標記為0(fake image),然後把真實的圖標記為1,這樣的training data 丟進我們的Discriminator Network做訓練,這就是每一次Discriminator訓練的步驟了,接下來我們來看Generator怎麼做,然後再把二個連結再一起。

Generator Network (生成器網路)

生成器網路的概念也很簡單,就是要訓練出一個Neural Network可以讓Discriminator分辨出來的結果越接近真實(1)的結果越好,我畫了以下的圖來理解生成器網路的訓練方式。



2020年10月12日 星期一

                                   好玩的創客開發套件丶M5Stack


近來發現一個很好玩的東西丶它的名字是M5stack!!!

它是乙種串連各式模組合成系統的硬體模塊可以完成你想要的夢想。M5Stack2016年在深圳成立的公司,M5Stack之名的含意為Modular5cmx5cm、堆疊。Module顧名思義為模組化、意指一切都像積木一樣直覺堆砌拆組、5cm是指印刷電路板僅有5公分長寬、Stackable則指可堆疊的。 

M5Stack產品的核心是Core Module、這個Module內由ESP32擔任主控晶片。Core的底部可以彈性換裝不同的Module、例如無線通訊模組、電池模組等,Module能夠以一個Core為基礎進行複數疊放連接、Core也可向外連接不同的Unit積木、Unit即為各種感測器或致動器、如加速度感測器、震動馬達等。

      依電氣連通而言大體為上述三者,除此之外M5Stack還提供機械、機構類型的Accessory配件、Base底座等、或直接以實現某一特定應用為取向的Application套件、智慧插座、迷你車等。使用M5Stack的好處是開發的創客不需要拿焊槍焊接、麵包板接線、直接將不同的積木拼湊連接即可實現與改變電路設計。其網址為https://m5stack.com/



             如何開始玩M5Stack、就是要下載開發工具、筆者使用的是Android系統。

開啓瀏覽器、然後訪問Arduino官方網站https://www.arduino.cc/en/Main/Software


          單擊“ Windows Installer、用於Windows XP及更高版本”下載Arduino IDE

單擊“僅下載”、雙擊Arduino安裝程序。

打開Arduino IDE然後導航到File-> Preferences->Settings

添加ESP32板管理器 URLhttps://dl.espressif.com/dl/package_esp32_index.json

將此鏈接用於ESP32板管理器URL複製到其他板管理器URL ESP32板管理器

然後點擊確定install即可。


Tools -> Board: -> Boards Manager...

Boards Manager窗口中搜索ESP32、找到它並單擊Install


打開Arduino IDE然後選擇Sketch-> Include Library-> Manage Libraries ...

搜索M5Stack找到它然後單擊Install



            這是M5stack核心開發套件。它是一個具有內置有用硬件的漂亮開發模塊可以使用Arduino Ide進行編程。

 


那麼我們就開始寫一個最簡單的萬年程式來測試一下環境。

#include <M5Stack.h>

  

// the setup routine runs once when M5Stack starts up

void setup(){

 

  // Initialize the M5Stack object

  M5.begin();

 

  /*

    Power chip connected to gpio21, gpio22, I2C device

    Set battery charging voltage and current

    If used battery, please call this function in your project

  */

  

  M5.Power.begin();

  M5.Lcd.setTextColor(GREEN, BLACK);

  M5.Lcd.setTextDatum(MC_DATUM);

   // LCD display

  M5.Lcd.print("Hello World");

}

 // the loop routine runs over and over again forever

void loop() {

//M5.update();

}

最後的成果如下圖:


新增說明文字


2020年4月16日 星期四


A Genetic Algorithm-based Beamforming Approach


在兹介紹一下所謂Beamforming(波束成型的天線陳列) 的架構,
LTE通訊啓,基地台為了提供更佳的服務,故使用天線陣列來極化電磁波以利QoS的提升5G的技術中, 幾乎其天缐唯一選項就是波束成型 (beamforming),  波束成型(Beamforming)技術可以大略的分成兩種:

第一種: 藉由量測到的通道係數, 設計傳送參數 (precoder), 最佳化通道
第二種: 透過多天線的相位偏移 (phase shifter), 決定電波傳遞強度模
本章節以Phase shifter 為其架構, 假設以1x9“矩陣”是線性代數來描述波束成型的天線陳列、
本文利用基因工程(Genetic Algorithm-based_來找出每一個Cell Weight以利其快速其值。



Source code with Python:

# -*- coding: utf-8 -*-

import numpy as np
import ga
import matplotlib.pyplot as plt
"""
The y=target is to maximize this equation ASAP:
    y = w1x1+w2x2+w3x3+w4x4+w5x5+6wx6+7Wx7+8Wx7+9Wx9
    where (x1,x2,x3,x4,x5,x6,x7,x8,x9)=(4,-2,3.5,5,-11,-4.7,5.0,2.1,3.1)
    What are the best values for the 9 weights w1 to w9?
    We are going to use the genetic algorithm for the best possible values after a number of generations.
"""

# Inputs of the equation.
equation_inputs = [4,-2,3.5,5,-11,-4.7,5.0,2.1,3.1]

# Number of the weights we are looking to optimize.
num_weights = len(equation_inputs)

"""
Genetic algorithm parameters:
    Mating pool size
    Population size
"""
sol_per_pop = 8
num_parents_mating = 4

# Defining the population size.
pop_size = (sol_per_pop,num_weights) # The population will have sol_per_pop chromosome where each chromosome has num_weights genes.
#Creating the initial population.
new_population = np.random.uniform(low=-4.0, high=4.0, size=pop_size)
print("new_population")
print(new_population)

"""
new_population[0,:]=[[ 2.58108145  2.42053643 -3.24720098  0.73414778  2.95861561 -3.95613747
   2.34638506 -1.96226993 -2.4267999 ]
new_population[1,:]= [ 0.50988501  3.66384758 -0.35728906 -3.36106177  0.60748192  0.34572714
   0.63256316  3.59916985  0.5291632 ]
new_population[2,:]= [-3.99726266 -1.05382206 -0.72618039 -0.69354415  3.6819675   1.42235044
   3.21944868  0.56545786 -2.53333267]
new_population[3,:]= [-2.01602033  3.21295543  0.1898793  -2.6094637   1.9595066  -2.04175245
  -0.63172776 -1.84656932 -3.39214779]
new_population[4,:]= [-1.65667992 -3.61456147 -2.08880869  0.51076383  0.06322565 -0.43551276
  -3.4748497  -2.61883376  2.93387284]
new_population[5,:]= [ 3.06194594 -1.81691236 -3.5244207   3.7688676  -0.78804301  1.7642483
  -1.63477098  2.0739781  -3.88904675]
new_population[6,:]= [-0.7733979  -0.59532673  0.22656214 -1.53837445 -1.72333473 -1.32000815
   1.8188883  -0.8669669  -1.29803437]
new_population[7,:]= [-3.52687898 -3.91602606  2.07969841 -2.29166193  0.58104485  0.79150089
  -3.13136887 -0.04240155  2.80654781]]
"""

best_outputs = []
num_generations = 10
for generation in range(num_generations):
    print("Generation : ", generation)
    # Measuring the fitness of each chromosome in the population.
    fitness = ga.cal_pop_fitness(equation_inputs, new_population)
    print("Fitness")
    print(fitness)

    best_outputs.append(np.max(numpy.sum(new_population*equation_inputs, axis=1)))
    # The best result in the current iteration.
    print("Best result : ", np.max(np.sum(new_population*equation_inputs, axis=1)))
    
    # Selecting the best parents in the population for mating.
    parents = ga.select_mating_pool(new_population, fitness, 
                                      num_parents_mating)
    print("Parents")
    print(parents)

    # Generating next generation using crossover.
    offspring_crossover = ga.crossover(parents,
                                       offspring_size=(pop_size[0]-parents.shape[0], num_weights))
    print("Crossover")
    print(offspring_crossover)

    # Adding some variations to the offspring using mutation.
    offspring_mutation = ga.mutation(offspring_crossover, num_mutations=2)
    print("Mutation")
    print(offspring_mutation)

    # Creating the new population based on the parents and offspring.
    new_population[0:parents.shape[0], :] = parents
    new_population[parents.shape[0]:, :] = offspring_mutation
    
# Getting the best solution after iterating finishing all generations.
#At first, the fitness is calculated for each solution in the final generation.
fitness = ga.cal_pop_fitness(equation_inputs, new_population)
# Then return the index of that solution corresponding to the best fitness.
best_match_idx = np.where(fitness == np.max(fitness))

print("Best solution : ", new_population[best_match_idx, :])
print("Best solution fitness : ", fitness[best_match_idx])



plt.plot(best_outputs)
plt.xlabel("Iteration")
plt.ylabel("Fitness")

plt.show()


2020年4月15日 星期三


                                     

Route Planning  With  Genetic Algorithm


Since we are given each location’s coordinates, let’s calculate the Manhattan distances between each pair of points and count the longitude and latitude differences to get a sense of direction . We can clean up timestamps a little and keep the original features which might look useless to us at first glance.

Locs : Traveler to go cities  list (note that locs is a list containing Location objects)
Level: number of evolution
Population : refers to a group consisting of several different paths
Variant  :  it is as the degree of variation between parents and children
Mutate_percent: refers to  percentage of a path is  mutated

Elite_save_percent : The shortest  path is regarded as the elite path (0.1 = 10% here)

At first, to define the  location:

 locations = []
    #longitude and latitude
    xs = [8, 50, 18, 35, 90, 40, 84, 74, 34, 40, 60, 74]
    ys = [3, 62, 0, 25, 89, 71, 7, 29, 45, 65, 69, 47]
    cities = ['Z', 'P', 'A', 'K', 'O', 'Y', 'N', 'X', 'G', 'Q', 'S', 'J']
    for x, y, name in zip(xs, ys, cities):
          locations.append(Location(name, x, y))

    my_locs=  locations

 Source code  with Python as below: 


import random as rd
import copy
from matplotlib import pyplot as plt

    
    

class Location:
    
    def __init__(self, name, x, y):
        self.name = name
        self.loc = (x, y)

    def distance_between(self, location2):
        assert isinstance(location2, Location)
        return ((self.loc[0] - location2.loc[0]) ** 2 + (self.loc[1] -                                      location2.loc[1]) ** 2) ** (1 / 2)
         
        
class Route:
    
    def __init__(self, path):
        # path is a list of Location obj
        self.path = path
        self.length = self._set_length()

    def _set_length(self):
        total_length = 0
        path_copy = self.path[:]
        from_here = path_copy.pop(0)
        init_node = copy.deepcopy(from_here)
        while path_copy:
            to_there = path_copy.pop(0)
            total_length += to_there.distance_between(from_here)
            from_here = copy.deepcopy(to_there)
        total_length += from_here.distance_between(init_node)
        return total_length
        
class GeneticAlgo:
    
    def __init__(self, locs, level=10, populations=100, variant=3, mutate_percent=0.01, elite_save_percent=0.1):
        self.locs = locs
        self.level = level
        self.variant = variant
        self.populations = populations
        self.mutates = int(populations * mutate_percent)
        self.elite = int(populations * elite_save_percent)
        
    def _find_path(self):
        # locs is a list containing all the Location obj
        locs_copy = self.locs[:]
        path = []
        while locs_copy:
            to_there =                                                                locs_copy.pop(locs_copy.index(rd.choice(locs_copy)))
            path.append(to_there)
        return path

    def _init_routes(self):
        routes = []
        for _ in range(self.populations):
            path = self._find_path()
            routes.append(Route(path))
        return routes
        
    def _get_next_route(self, routes):
        routes.sort(key=lambda x: x.length, reverse=False)
        elites = routes[:self.elite][:]
        crossovers = self._crossover(elites)
        return crossovers[:] + elites

    def _crossover(self, elites):
        # Route is a class type
        normal_breeds = []
        mutate_ones = []
        for _ in range(self.populations - self.mutates):
            father, mother = rd.sample(elites[:4], k=2)
            index_start = rd.randrange(0, len(father.path) - self.variant - 1)
            # list of Location obj
            father_gene = father.path[index_start: index_start + self.variant]
            father_gene_names = [loc.name for loc in father_gene]
            mother_gene = [gene for gene in mother.path if gene.name not in father_gene_names]
            mother_gene_cut = rd.randrange(1, len(mother_gene))
            # create new route path
            next_route_path = mother_gene[:mother_gene_cut] + father_gene + mother_gene[mother_gene_cut:]
            next_route = Route(next_route_path)
            # add Route obj to normal_breeds
            normal_breeds.append(next_route)

            # for mutate purpose
            copy_father = copy.deepcopy(father)
            idx = range(len(copy_father.path))
           # gene1, gene2 = rd.shuffle(idx)
            gene1, gene2 = rd.sample(idx, 2)
            copy_father.path[gene1], copy_father.path[gene2] = copy_father.path[gene2], copy_father.path[gene1]
            mutate_ones.append(copy_father)
        mutate_breeds = rd.sample(mutate_ones, k=self.mutates)
        return normal_breeds + mutate_breeds  
           
    def evolution(self):
        routes = self._init_routes()
        for _ in range(self.level):
            routes = self._get_next_route(routes)
        routes.sort(key=lambda x: x.length)
        return routes[0].path, routes[0].length
    
    
  
     
if __name__ == '__main__':
    # obj = GeneticAlgo()
    
    locations = []
    xs = [8, 50, 18, 35, 90, 40, 84, 74, 34, 40, 60, 74]
    ys = [3, 62, 0, 25, 89, 71, 7, 29, 45, 65, 69, 47]
    cities = ['Z', 'P', 'A', 'K', 'O', 'Y', 'N', 'X', 'G', 'Q', 'S', 'J']
    for x, y, name in zip(xs, ys, cities):
          locations.append(Location(name, x, y))
    my_locs=  locations
       
    my_algo =  GeneticAlgo(my_locs, level=40, populations=150,                variant=2, mutate_percent=0.02, elite_save_percent=0.15)
    variant=2, mutate_percent=0.02, elite_save_percent=0.15)
    best_route, best_route_length = my_algo.evolution()
    best_route.append(best_route[0])
    print([loc.name for loc in best_route], best_route_length)
    print([(loc.loc[0], loc.loc[1]) for loc in best_route],                                                                             best_route_length)   
    fig, ax = plt.subplots()
    ax.plot([loc.loc[0] for loc in best_route], [loc.loc[1] for loc in                               best_route], 'red', linestyle='-', marker='')
    ax.scatter(xs, ys)
    for i, txt in enumerate(cities):
        ax.annotate(txt, (xs[i], ys[i]))

    plt.show()                    

2020年4月13日 星期一



                     退休生活如何規劃財務


              按滙豐集團曾經公布一份「未來的退休生活」調查結果,它們在16個國家調查超過18000名受訪者。調查發現:全球超過31%已退休人士表示,他們很後悔沒有提早為退休做準備。而台灣已退休人士,後悔沒有提早為退休做準備的比率高達51%,排名全球第一。

人生短短歳月從娃兒啟程至人生終點短則數十年長則百年。如何安排有尊嚴的退休生活應是一門課程。







在此就筆者的經驗分享給即將準備退休的參考。综觀各式理財工具, 股市,基金及房價等歷年波動曲線圖,
臺灣因淺碟經濟,靠外銷謀生故股海中,隨著消息面坑殺散戶時有所聞,且內線交易一直是臺灣股市處於大戶及公司派的暗器,在消息不透明及經營者惡意欺騙。甚小有散戶獲利。故股海如死海般只會讓散戶鎩羽而歸!

如下圖股市因外在的變動,台股近30年加權指數變化比房市變動劇烈。在準備退休的人士除非看清股市波動,一般建議你買的是定存股 ,即股價變動小且每年有比定存高的股利收入。




2: 台股 30 (取自CMoney 月刋)

反觀台灣房市波動較少,房市30年來除了SARS 期間有修正之外其指數尚维持正成長。在房市要獲利需
要一些基本功,首重地區,交通便捷及生活機能。可在蛋黃區中物色相對便宜的屋件。房子外觀及屋齡非重點,重點是入手的價格需低於
周邊物件就有獲利空間。也許用於自住或出租因其控制權100%由自己調控。故我個人大部份資產放置於房市,透過出租來維持財務自由度。



3: 台灣房價指數 (取自https://group.dailyview.tw/article/detail/833)







精選文章

Active Cooler/Warner system with thermoelectric cooler

Cooler 系統包括了 DC/DC Converter, 與主機通界面 , 感测線路 , 風量葉片 ,DC Motor 等 , 控制器感测線路的回饋資料供 PID 運算出最佳控制模式。在系統軟件架構上主要包括四種類型的軟體規劃,分別是資料庫系統 (Database) 、 ...