1. 원래 Axboot의 처리방식

  : 신규 행추가 후 기존의 키값과 동일한 키값을 입력 후 저장시 원래있던 데이터를 행추가시 입력한 데이터로 

    업데이트 해버린다.

   ==> 실제 업무화면에서는 사고가 발생할 여지가 있는 부분임.

          실수로 기존의 키값과 동일한 값을 추가하여 나머지 데이터는 다른값을 입력하고 저장했을 경우

          의도치 않게 기존에 있던 데이터가 업데이트되어 사고가 발생할 수 있다.

          보통은 신규로 행추가 했을 경우 기존값과 중복된 키값을 입력했을 경우 에러를 벹어내도록 구현된다.

   1) 기존 처리방식의 예시화면

      - 기존데이터 상태


  - 기존에 있는 데이터와 중복되는 제품코드가 11 인 데이터를 추가함(제품명,원산지,매입가격,판매가격은 다르게 입력)

    (데이터가 많으면 인지하지 못할 수 있음)


  - 저장시 기존의 데이터가 있다는 경고 없이 그냥 저장됨.


2. 중복체크로직 추가

  1) javascript에서 로직 추가

     - 조회 후 조회값인지 화면에서 행추가한 값인지 상태값 체크할 수 있는 "__searched__" key를 조회결과 처리부분의

      json 에 추가해준다. 

      ==>이유 : 신규로 행추가 후 중복값 입력 후 저장했을 경우 에러메시지가 발생해서 중복값을 삭제 후 

                    저장했을 경우 화면에서는 없어졌지만 계속 값이 deletedList라는 json key에 "__create__" key로 저장되어있어

                    계속 중복된다는 메시지가 리턴됨. 그래서 화면에서만 추가/삭제된 것은 deletedList에서 없애주기 위해서는

                    기존에 조회된 값인지의 여부를 판단할 필요가 있어 "__searched__" flag가 필요함.

    - 저장(PAGE_SAVE) 시 에러가 발생할 경우 메시지처리하는 부분을 추가함.

    - Grid의 delRow 부분에 행삭제시 기존에 조회된 값이 아닌 경우 불필요하게 데이터가 서버로 날라가는것을

       방지하기 위해 deletedList에서 "__searched__" key가 없는(undefined) 것은 삭제하는 로직 추가


  2) Controller 에서 로직 추가

    - Exception을 받아 화면으로 넘기는 처리한다.

      ==> axboot에 있는 class를 활용한다. 

   : ApiException 으로 받아 com.chequer.axboot.core.controllers.BaseController.handleApiException을 화면으로 넘긴다.


  3) ProductService 에서 로직 추가

    - 신규추가된 데이터에 대해 기존에 있는데이터인지 체크해서 중복 시 ApiException으로 메시지를 리턴한다.


   

다음 글에 중복등록체크로직 추가 -2 에서 실제 구현되는 방식을 보시겠습니다.


어때요? 도움이 많이 되셨나요? ~~~~~~~

1. Grid의 행추가시 자주 사용하는 값을 초기값으로 셋팅

- 앞서 작성했던 프로그램의 연속성상에서 간단히 수정만 하면 됨.

- webapp>assets>js>view>shopmng>product.js 를 수정한다. 

- gridView 하위에 있는 addRow function 에 초기값을 셋팅해준다.


2. 예제

  : 아래의 예는 원산지를 한국(KR)로 셋팅하는 예제이다.

addRow: function () {

    this.target.addRow({__created__: true, origin: "KR"}, "last");

 },


- grid의 원산지 컬럼인 origin 에 "KR"로 셋팅하면 행추가시 바로 "KR"로 셋팅된다.





어때요? 도움이 많이 되셨나요? ~~~~~~~

1. 사용용도

  : 가게를 운영하거나 할때 아르바이트를 고용해야 되는 상황에서 다음과 같은 다양한 조건들을 충족시키면서

    사업주 입장에서는 전체적인 운영비가 낮게 나올 수 있는 방법이 필요할 경우 엑셀의 해찾기 기능을 이용하여

    쉽게 해결할 수 있다.


   * 다양한 조건들

    1) 아르바이트별 임금이 다르다.

    2) 아르바이트마다 필수 근무시간을 보장해줘야 한다.

    3) 아르바이트마다 희망 근무시간이 다르다. 

    4) 시간별 필요 근무자수가 다르다. 


   위 조건들은 현장에서 일상적으로 일어날 수 있는 상황들이다. 

   주먹구구식으로 배치하다보면 사업주 입장에서는 과도한 운영비 또는 필요근무자를 배치못하는 상황이 발생할 수 있고,

   실제 아르바이트 입장에서는 사업주가 주먹구구식으로 배치하다보니 자신이 실제 근무하지 못하는 시간까지

   억지로 배정받을 수 있는 상황이 발생할 것이다.


2. 구현결과

  : 앞서도 얘기했지만 결과물을 먼저 봐야 그 이후에 세부적으로 구현시 그림이 그려진다.

   아래는 위 다양한 조건들을 해결하면서 하루 총 시급이 최소화가 되는 경영과학 정수계획법 모델로 설계한 결과물이다.


 3. 구현방법

   1) 현재 상황 및 필요조건에 대해 세세하게 적어본다.

      a) 가게의 운영시간은 09시부터 22까지이다.

      b) 아르바이트는 4명으로 운영한다.

      c) 아르바이트별 임금이 다르다.

      d) 아르바이트마다 필수 근무시간을 보장해줘야 한다.

      e) 아르바이트마다 희망 근무시간이 다르다. 

      f) 시간별 필요 근무자수가 다르다. 

      g) 시급이 최소화가 되도록 시간배정을 하고싶다.


   2) 그 다음 상황 및 조건을 표현할 수 있는 도표를 그린다.

      a) 위 그림과 같이 위에는 09시부터 22시까지 아르바이트가 근무가능한 시간을 표로 만들어 본다.

         ( 1은 근무가능, 2는 불가능 )

      b) 아래에는 해찾기 시뮬레이션으로 결정되어질 결과물의 도표를 그려준다.

          옅은 파란색 부분이 해찾기를 통해 변경되어질 부분이다. 초기에는 아무값으로 셋팅되어도 상관없다.

   

   3) 그 다음은 결과물에서 충족해야할 조건들을 옆, 아래에 적어준다.

      - 시간별 필요아르바이트수는 제일 오른쪽에 입력한다.

      - 아르바이트 사람별로 최소로 지켜줘야할 근무시간은 아래쪽에 입력한다. 

      - 최종결정된 하루근무시간을 곱해서 하루 총 시급의 합계를 계산하기 위해 아르바이트별 시급을 적어준다.

      - 상단에 "가능-필요" 항목은 상단에 아르바이트 가능시간을 입력할 때 필요한 시간보다 가능한 시간이 

        작으면 안되므로 입력할 때 바로 체크하기 위해 만들어놓았다.


   4) 아래와 같이 수식을 입력한다.

      - 몇자치고 복사하면 쉽게 완성되므로 수식은 따로 적어두지 않겠다.


 - 참고로 SUMPRODUCT 라는 함수가 자주 사용되는데, 의미는 배열의 같은 위치끼리 곱해서 전체를 더한결과를 쉽게 

   할 수 있는 함수이다. 새로나온건가? 하시는 사람도 있는데 엑셀 초기버전부터 있었던걸로 알고있다.

   아래를 보면 금방 알 수 있다.

   

 

 A

 1

 2

 2

 6

   

  = SUMPRODUCT(A1:B1,A2:B2)   ==> 이 의미는 A1*B1 + A2*B2  로 결과값은 2*6 + 5*8 = 52 가 된다.

이걸 안쓰면 일일이 풀어서 더해도 된다...원하신다면....ㅋ


   5) 위와같이 설계가 다 완료되면 데이터> 해찾기를 실행해서 제약조건들을 입력한다.

      - 아래 조건에 변경될 부분에 2진수 조건을 넣은 이유는 0과 1로만 나오도록 하기 위함이다.



   6) 위 조건을 입력 후 해법선택은 단순 LP (선형회귀)를 선택해도 답이 쉽게 나온다.

    * 참고 

- GRG(Generalized Reduced Gradient) : 비선형 문제에 사용

- 단순LP :   -  선형 문제에 사용

- Evolutionary  -  비곡선 문제에 사용


그러면 아래와 같이 아르바이트를 언제 누구를 배치하고 하루 총시급의 최소값이 얼마나 나오는지를 알 수 있다.


어때요? 도움이 많이 되셨나요? ~~~~~~~



1. 사전준비

  1) Tensorflow 1.7 설치 

     : inception V3를 실행하기 위해 tensorflow 는 1.7 버전 이상을 설치해야 검증(TEST)시 오류가 나지 않는다.

      앞 강좌에서 설치한 Tensorflow 1.6을 1.7로 업그레이드 후 진행한다.

      아래 명령어 실행시 앞서 설치한 python 3.5에 맞는 tensorflow는 1.7 까지 가능하므로 1.7을 설치하겠다.

pip install "tensorflow==1.7.0"
pip install "tensorflow-gpu==1.7.0"


D:\ML2\inception\example_code>pip install "tensorflow==1.7.0"
Collecting tensorflow>=1.7.0
  Downloading https://files.pythonhosted.org/packages/af/5b/695e2e66feb27742a78f938d8369cc874b5fc7082193c3352c9db599af01/tensorflow-1.11.0-cp35-cp35m-win_amd64.whl (46.9MB)
    55% |#################               | 26.1MB 93kB/s eta 0:03:43
	
D:\ML2\inception\example_code>pip install "tensorflow-gpu==1.7"
Collecting tensorflow-gpu==1.7
  Downloading https://files.pythonhosted.org/packages/57/9a/81144ee2cdf50c6e7e5ee3e17e2d05dc26173eced2f1696aa986c0b58f57/tensorflow_gpu-1.7.0-cp35-cp35m-win_amd64.whl (86.7MB)
    17% |#####                           | 15.4MB 229kB/s eta 0:05:12


   *참고 : tensorflow 1.6 에서 TEST를 실행하면 아래와 같은 오류가 발생한다.

python label_image.py --graph=D:/tmp/output_graph.pb --labels=D:/tmp/output_labels.txt --input_layer=Placeholder --output_layer=final_result  --image=D:/ML2/inception/flower_photos/daisy/21652746_cc379e0eea_m.jpg

Caused by op 'import/module_apply_default/InceptionV3/InceptionV3/Mixed_7b/Branch_1/Conv2d_0a_1x1/Conv2D/ReadVariableOp', defined at:
  File "label_image.py", line 118, in 
    graph = load_graph(model_file)
  File "label_image.py", line 33, in load_graph
    tf.import_graph_def(graph_def)
  File "D:\ML_Program\Python35\lib\site-packages\tensorflow\python\util\deprecation.py", line 432, in new_func
    return func(*args, **kwargs)
  File "D:\ML_Program\Python35\lib\site-packages\tensorflow\python\framework\importer.py", line 553, in import_graph_def
    op_def=op_def)
  File "D:\ML_Program\Python35\lib\site-packages\tensorflow\python\framework\ops.py", line 3271, in create_op
    op_def=op_def)
  File "D:\ML_Program\Python35\lib\site-packages\tensorflow\python\framework\ops.py", line 1650, in __init__
    self._traceback = self._graph._extract_stack()  # pylint: disable=protected-access

   2) 소스 내부적으로 tensorflow_hub 모듈을 사용하므로 pip install tensorflow_hub 명령어로 모듈을 설치하자.

D:\ML2\inception\example_code>pip install tensorflow_hub
Collecting tensorflow_hub
  Downloading https://files.pythonhosted.org/packages/5f/22/64f246ef80e64b1a13b2f463cefa44f397a51c49a303294f5f3d04ac39ac/tensorflow_hub-0.1.1-py2.py3-none-any.whl (52kB)
    100% |################################| 61kB 833kB/s
Requirement already satisfied: protobuf>=3.4.0 in d:\ml_program\python35\lib\site-packages (from tensorflow_hub) (3.5.2.post1)
Requirement already satisfied: six>=1.10.0 in d:\ml_program\python35\lib\site-packages (from tensorflow_hub) (1.11.0)
Requirement already satisfied: numpy>=1.12.0 in d:\ml_program\python35\lib\site-packages (from tensorflow_hub) (1.14.3)
Requirement already satisfied: setuptools in d:\ml_program\python35\lib\site-packages (from protobuf>=3.4.0->tensorflow_hub) (28.8.0)
Installing collected packages: tensorflow-hub
Successfully installed tensorflow-hub-0.1.1

  3) 학습용 이미지 다운로드 

    - 폴더를 구분하여 폴더명 아래에 관련이미지들을 넣으면 본인이 원하는 이미지로 학습이 가능하다

    - 아래 경로에서 샘플사진들을 받아  압축을 푼다.  

    - 다운로드 링크 : http://download.tensorflow.org/example_images/flower_photos.tgz

    - 저자의 경우 D:\ML2\inception\ 하위경로에 압축을 풀기로 한다.

    - 저자의 폴더구조는 다음과 같다.\

   4) 학습과 테스트를 위한 소스코드 다운로드 

      : 저자의 경우 위 폴더 중 example_code 폴더 內에 다운로드 하였음.

      - 학습용 소스코드 다운로드 

        : https://github.com/tensorflow/hub/raw/master/examples/image_retraining/retrain.py

      - 테스트용 소스코드 다운로드 

        : https://github.com/tensorflow/tensorflow/raw/master/tensorflow/examples/label_image/label_image.py


2. 이미지 학습 및 tensorboard 실행

   1) 이제 모든 재료가 준비가 되어있으니 아래 명령어를 입력하여 학습을 돌려주기만 하면 된다.    

      python retrain.py --image_dir D:/ML2/inception/flower_photos

 

      - 컴퓨터가 공부할 수 있는 시간을 기다려주자.

      - 소스상에 학습되는 데이터는 소스코드가 있는 드라이버(D:) 의 tmp 폴더 하위에 만들어진다.



   2) 학습 중간에 학습이 진행되는 과정을 보고자 하면 Tensorboard 를 실행하여 event 분석그래프를 보면 된다.

       - 또다른 cmd창을 띄우고 아래 명령어를 실행하면 된다.

          (event파일은 retrain_log 폴더 안에 있다 - 소스상에 그렇게 지정되어 있음)

         tensorboard --logdir D:/tmp/retrain_logs


      - 위에 tensorboard 서버가 실행되면 그 아래에 http로 시작하는 주소가 나온다.

        브라우저를 실행하여 http://WN31093:6006 으로 접속해보자.

        그러면 아래와 같이 가시적으로 분석가능한 화면이 나온다.

  3) 학습결과  

     - 학습이 다 완료되면 D:/temp 하위에 output_graph.pb , output_labels.txt 파일이 생긴다.

     - .pb 파일은 inception 내부에서 이미지를 판단하는 로직에 의해 flower_photos 하위에 있는 개별 이미지들을

       학습한 결과 파일이며, output_labels.txt 는 분류를 적어놓은 text파일이다.. 

     - 실제 하나의 테스트 이미지에서 여러가지 원하는 이미지를 동시에 인식시키기 위해서는

       수기로 labeling을 하는 수고를 거쳐야 할 것이다. (직접 labeling 을 해보려면 라쿤예제가 있다..github 참고)


3. TEST실행

  1) 기존에 학습하기위해 사용했던 이미지 중 임의의 이미지를 골라 TEST를 해본다.

      아래는 기존에 사용했던 이미지 중 daisy 폴더안에 있는 이미지로 테스트를 하는 내용이다.


python label_image.py --graph=D:/tmp/output_graph.pb --labels=D:/tmp/output_labels.txt --input_layer=Placeholder --output_layer=final_result  --image=D:/ML2/inception/flower_photos/daisy/21652746_cc379e0eea_m.jpg

   - 그러면 아래와 같은 학습결과가 나온다.

   

D:\ML2\inception\example_code>python label_image.py --graph=D:/tmp/output_graph.pb --labels=D:/tmp/output_labels.txt --input_layer=Placeholder --output_layer=final_result  --image=D:/ML2/inception/flower_photos/daisy/21652746_cc379e0eea_m.jpg
날짜.시간.892098: I T:\src\github\tensorflow\tensorflow\core\platform\cpu_feature_guard.cc:140] Your CPU supports instructions that this TensorFlow binary was not compiled to use: AVX2
날짜.시간.842399: I T:\src\github\tensorflow\tensorflow\core\common_runtime\gpu\gpu_device.cc:1344] Found device 0 with properties:
name: GeForce MX150 major: 6 minor: 1 memoryClockRate(GHz): 1.5315
pciBusID: 0000:01:00.0
totalMemory: 2.00GiB freeMemory: 1.62GiB
날짜.시간.859336: I T:\src\github\tensorflow\tensorflow\core\common_runtime\gpu\gpu_device.cc:1423] Adding visible gpu devices: 0
날짜.시간..973613: I T:\src\github\tensorflow\tensorflow\core\common_runtime\gpu\gpu_device.cc:911] Device interconnect StreamExecutor with strength 1 edge matrix:
날짜.시간..983104: I T:\src\github\tensorflow\tensorflow\core\common_runtime\gpu\gpu_device.cc:917]      0
날짜.시간..988281: I T:\src\github\tensorflow\tensorflow\core\common_runtime\gpu\gpu_device.cc:930] 0:   N
날짜.시간..994075: I T:\src\github\tensorflow\tensorflow\core\common_runtime\gpu\gpu_device.cc:1041] Created TensorFlow device (/job:localhost/replica:0/task:0/device:GPU:0 with 1391 MB memory) -> physical GPU (device: 0, name: GeForce MX150, pci bus id: 0000:01:00.0, compute capability: 6.1)
날짜.시간..111074: I T:\src\github\tensorflow\tensorflow\core\common_runtime\gpu\gpu_device.cc:1423] Adding visible gpu devices: 0
날짜.시간..118736: I T:\src\github\tensorflow\tensorflow\core\common_runtime\gpu\gpu_device.cc:911] Device interconnect StreamExecutor with strength 1 edge matrix:
날짜.시간..127297: I T:\src\github\tensorflow\tensorflow\core\common_runtime\gpu\gpu_device.cc:917]      0
날짜.시간..133590: I T:\src\github\tensorflow\tensorflow\core\common_runtime\gpu\gpu_device.cc:930] 0:   N
날짜.시간..139888: I T:\src\github\tensorflow\tensorflow\core\common_runtime\gpu\gpu_device.cc:1041] Created TensorFlow device (/job:localhost/replica:0/task:0/device:GPU:0 with 1391 MB memory) -> physical GPU (device: 0, name: GeForce MX150, pci bus id: 0000:01:00.0, compute capability: 6.1)
날짜.시간.078684: W T:\src\github\tensorflow\tensorflow\core\common_runtime\bfc_allocator.cc:219] Allocator (GPU_0_bfc) ran out of memory trying to allocate 1.91GiB. The caller indicates that this is not a failure, but may mean that there could be performance gains if more memory were available.
날짜.시간.887221: W T:\src\github\tensorflow\tensorflow\core\common_runtime\bfc_allocator.cc:219] Allocator (GPU_0_bfc) ran out of memory trying to allocate 1.41GiB. The caller indicates that this is not a failure, but may mean that there could be performance gains if more memory were available.
날짜.시간.904741: W T:\src\github\tensorflow\tensorflow\core\common_runtime\bfc_allocator.cc:219] Allocator (GPU_0_bfc) ran out of memory trying to allocate 1.69GiB. The caller indicates that this is not a failure, but may mean that there could be performance gains if more memory were available.
날짜.시간.923649: W T:\src\github\tensorflow\tensorflow\core\common_runtime\bfc_allocator.cc:219] Allocator (GPU_0_bfc) ran out of memory trying to allocate 1.98GiB. The caller indicates that this is not a failure, but may mean that there could be performance gains if more memory were available.
daisy 0.9976986
sunflowers 0.001372812
dandelion 0.0005049626
tulips 0.0003564248
roses 6.7078516e-05

  - 위의 결과를 보면 daisy 가 0.9976986로 100%에 가까운 신뢰도를 가지므로 

    컴퓨터는 테스트 이미지가 daisy로 판단한다. 


뭔가 지식을 얻어가셨나요? 


※ Table 좌측,상단 조건으로 값 가져오기(index, match이용)


1. 사용용도

   : 엑셀에서 아래와 같이 Table 형태로 작성된 것이 있을 때 좌측, 상단 조건과 일치하는 값을 

     뽑아내야 할 경우가 있다. 이럴 때 index와 match함수를 이용하여 원하는 값을 찾을 수 있다.



2. 사용방법

   1) 아래와 같이 제품별 월매출 정보가 있는 Table을 그린다. 

* 제품별 월매출 (단위:만원)

제품            매장

A매장

B매장

C매장

D매장

E매장

제품A

         1,500

         2,500

     1,320

     2,350

      1,100

제품B

         1,700

         2,300

     2,300

     2,200

      1,600

제품C

         1,350

         2,200

      750

     1,600

      2,300

제품D

         1,260

         3,600

     1,100

     1,700

      3,000

매장합계

         5,810

       10,600

     5,470

     7,850

      8,000


   2) 특정제품이 얼마나 팔렸는지 따로 정리하고자 한다.(대량으로 처리할때 유용)

      : 예시로는 제품C가 C매장에서 얼마나 팔렸는지 찾고자 함.

     - INDEX함수 : INDEX(가져올 값 범위, 왼쪽범위에서 row좌표, 왼쪽범위에서 col좌표)

     - MATCH함수 : MATCH(찾을값, 찾을곳범위, 정확도) , 정확도는 일치하는값이라 보통 0 셋팅

       정확도 참고       

     

   3) 함수설명

찾을제품

찾는매장

찾는값

제품C

C매장

=INDEX($C$4:$G$8,MATCH(B13,$B$4:$B$7,0),MATCH(C13,$C$3:$G$3,0))




이해가 잘 되셨는지 모르겠습니다.^^


만족하셨나요? ~~~~~~~

+ Recent posts