반응형

Build의 순서는 아래와 같다.

소스코드 -> 전처리 -> 컴파일 -> 링크 -> 실행

C언어를 처음 공부할 때, #define을 사용하지 않으면 전처리 과정을 거치지 않는다고 생각한 적이 있다.

#으로 시작하는 문장은 전부 전처리기 지시자임에도 #include는 전처리기라고 생각하지 않았다. 항상 C언어를 실습할 때, 의무적으로 #inlcude <stdio.h>를 작성한 폐해이다.

전처리란 무엇인가?

컴파일 전에 처리해야 하는 일이고 전처리를 수행하는 장치를 전처리기라고 한다.

전처리기는 헤더 파일을 불러오거나, 소스 파일 내부의 특정 문자열을 상수 또는 문자로 치환하거나, 조건에 따라서 코드의 일부를 컴파일하거나 컴파일하지 못하게 하는 선택 기능을 제공한다.

궁금증이 하나 발생한다.

#define은 왜 사용하는가? 단순히 변수나 함수를 선언 및 호출하면 되지 않는가? 일반 변수 및 함수와 매크로(#define)의 차이는 무엇인가?

이를 이해하기 위해선 컴파일 단계를 이해할 필요가 있다.

컴파일이란 무엇인가? 기계어로 번역하는 번역기이다. 왜 기계어로 번역하는가? 소스 코드는 사람이 이해하기 쉬운 문장이며, 기계는 이해할 수 없다. 그러므로 기계가 이해할 수 있는 문장으로 번역해줘야 한다.

C언어가 생기기 이 전, 개발자들은 기계(컴퓨터, CPU)를 직접 제어하기 위해 기계어(어셈블리어)를 직접 작성하였다. 하지만 CPU는 다양했고, CPU의 종류에 따라 어셈블리어 작성하는 방법도 각기 달랐다고 하며, 간단한 프로그램에도 코드가 굉장히 길어졌다. 

이 문제점을 해결하기 위해, 기계어를 직접 사람이 작성하지 않아도 되는 번역기를 개발했는데 그것이 컴파일러이다. 개발자들은 더 이상 기계의 종류를 상관하지 않아도 된다.


C언어는 소스코드 중복을 줄이고 코드의 재사용성을 높이기 위해서 함수를 제공한다. 하지만, 함수는 호출될 때 *스택 프레임이 일어나기 때문에 속도가 느려지는 단점이 있다. 따라서 코딩할때는 매크로를 함수와 같은 기능으로 작성하지만 실제 기계어로 번역될 때는 직접 코딩한 것처럼 처리(치환, 전처리 단계에서 매크로가 소스코드로 변환)된다.

함수 호출 시, 스택이라는 메모리 공간에 매개 변수, 반환 포인터 값, 지역 변수 순서로 저장되는 값을 스택 프레임이라고 한다.

즉, 저장 공간인 스택을 메모리 낭비를 줄이고 실행 속도를 높이기 위해 매크로를 사용한다. 하지만 매크로는 소스코드로 바로 변환되므로 실행 파일 크기가 커지며, 재귀호출을 할 수 없다는 단점을 가지므로 적절하게 사용하는 것이 중요하다. 

요즘엔 컴퓨터의 메모리가 굉장히 넉넉하기 때문에 메모리 걱정을 하지 않을 때가 많지만, 메모리 공간이 넉넉치 않은 임베디드 시스템과 같은 환경에서는 매크로를 많이 사용한다.


아래 매크로 함수와 일반 함수 예시를 보겠다.

#include <stdio.h>

#define MUL(x, y) x*y

int mul(x, y)
{
	return x*y;
}
int main()
{
	int a, b;
    
    scanf("%d %d", &a, &b);
    printf("%d", MUL(a+1, b+1));
    printf("%d", mul(a+1, b+1));
}

// result
// a=3, b=4 입력
// 8
// 20

왜 결과값이 8, 20으로 다른 값이 나올까?  매크로는 전처리 단계에서 소스 코드로 변경된다고 했다. 

MUL(a+1, b+1)을 소스 코드로 치환되면 a+1*b+1 이다.

그러므로 3+1*4+1로 계산되어 8이라는 결과가 출력된다. mul과 같은 결과를 내기 위해선, 

#define MUL(x, y) ((x) * (y)) 로 변경하면 된다. 소스코드로 치환하게 되면, ((a+1)*(b+1))이다.

728x90
반응형
반응형
참고
LoRa Alliance Link Layer Specification v1.0.2

Confirmed mode : Confirmed mode에서 모든 Uplink(End Device(ED)에서 Network Server(NS)로 전송된 패킷) 후에 Class A ED는 두 개의 수신 창(RX)을 사용하여 확인 알림으로 NS의 ACK를 요구합니다.

 

Unconfirmed mode : Unconfirmed mode에서는 NS에서 ED로의 Downlink(DL) ACK가 필요하지 않습니다.

 

Unconfirmed mode
Confirmed mode

( GW : Gateway )
각 ED에는 전송된 데이터 Frame 수를 추적하기 위한 두 개의 Frame Counter(FCnt)가 있다. 
ex) FCnt Uplink(FCntUp)와 FCnt Downlink(FCntDown)
위 글은 Unconfirmed mode와 Confirmed mode의 차이를 간단히 도식하기 위해 Uplink만 언급한다.

FCntUp은 ED가 Uplink를 성공하면 1씩 증가한다.
(MAC Layer의 파라미터 중 하나로 16bits(2^16까지 표현 가능), 32bits(2^32까지 표현 가능)를 선택할 수 있다. 만약, FCnt가 16bits로 선언됐고, FCntUp이 2^16-1 이상까지 증가하였다면, 다음은 0으로 초기화한다.)

 


Unconfirmed mode와 Confirmed mode의 가장 큰 차이는 ACK 유무입니다. 하지만 또 다른 차이는 재전송(Retransmission) 입니다. 

 

Retransmission은 말 그대로 Uplink Packet을 GW가 수신 받지 못했을 경우를 대비해 재전송하는 방법입니다. 당연히 똑같은 Packet을 전송하므로 FCntUp은 증가하지 않습니다.

(nb는 전송 횟수입니다.)

 

unconfirmed mode retransmission

unconfirmed mode는 무조건 똑같은 패킷을 retransmission를 설정한 만큼 재전송합니다. 그래서 보통 unconfirmed mode는 retransmission을 사용하지 않습니다.

confirmed mode retransmission

confirmed mode의 경우, Uplink Packet에 대한 ACK를 수신하면, 재전송하지 않고 다음 Packet을 전송합니다. 하지만 ACK를 수신하지 못하면, 재전송을 시작하는데, 아래 테이블과 같이 DR을 설정하는데, 이를 ED의 Adaptive Data Rate(ADR)이라고 합니다.

Data-Rate Adaptation during Message Retransmissions in confirmed mode

 


unconfirmed mode와 confirmed mode를 간략히 설명했습니다. 

 

TTN에서 모범 사례라 하여 unconfirmed mode와 confirmed mode에 대해 언급한 부분이 있습니다.

https://www.thethingsindustries.com/docs/devices/best-practices/

 

Best Practices

 

www.thethingsindustries.com

 

confirmed mode가 꼭 필요하지 않다면, unconfirmed mode 사용하세요.

LoRaWAN에서 unconfirmed mode를 지향하는 이유는  ALOHA 방식과 유사하기 때문입니다.

 

ED가 몇 백개 정도라면 괜찮겠지만, ED가 몇 만개가 된다면 채널의 혼잡도가 가중되기 때문에 최대한 불필요한 Packet을 줄이는 것이 중요합니다. confirmed 모드는 ACK가 필요하므로 채널을 혼잡하게 한다고 판단하는 것 같습니다. 

728x90
반응형
반응형

https://www.thethingsnetwork.org/docs/lorawan/end-device-activation/

 

End Device Activation

Every end device must be registered with a network before sending and receiving messages. This procedure is known as activation. There are two activation methods available: Over-The-Air-Activation (OTAA) - the most secure activation method for end devices.

www.thethingsnetwork.org

  • Over-The-Air-Activation (OTAA) - the most secure activation method for end devices. Devices perform a join procedure with the network, during which a dynamic device address is assigned and security keys are negotiated with the device.
  • Activation By Personalization (ABP) - requires hardcoding the device address as well as the security keys in the device. ABP is less secure than OTAA and also has the downside that devices can not switch network providers without manually changing keys in the device.

OTAA와 ABP의 차이는 인증방식이다.

 

ABP는 사전에 Application_Key, Network_Key를 가지고, 하나의 채널을 Default로 고정하여 사용한다. 그러므로 Join_Request, Join_Accept 과정이 필요하지 않는다.

 

반면 OTAA는 ABP와 달리 네트워크 첫 진입 시  Join_Request, Join_Accept 를 주고 받으며, 인증을 받는다. 아래 그림은 OTAA 메세지 흐름을 설명한다. 

OTAA Message Flow

 

End_Device가 Join_Request 메세지를 업링크(Up_Link)한다. Application_Server가 Join_Request에 대한 세션 키를 생성하면 Join_Accept 메세지를 End_Device로 다운링크(Down_Link)한다. (이는 기본적으로 Class_A로, End_Device 주도방식이다.)

 

여기서 Join_Accept 메세지 안의 CFList가 중요하다. 

CFList(16bytes) – contains the optional list of channel frequencies to be used for the end device 

 

Join_Accept 메세지 안에는 End_Device가 Channel_Frequency를 사용할  CFList가 들어 있다. 여기서 ABP와 큰 차이점을 가진다. ABP는 하나의 Channel_Frequency를 사용한다면, OTAA는 CFList를 통해 Channel_Frequency가 바뀐다.

 


MBED 구현 부분이다. 

https://github.com/ARMmbed/mbed-os-example-lorawan

 

GitHub - ARMmbed/mbed-os-example-lorawan: Simple LoRaWAN example application for mbed OS

Simple LoRaWAN example application for mbed OS. Contribute to ARMmbed/mbed-os-example-lorawan development by creating an account on GitHub.

github.com

 

mbed_app.json 파일 안에 OTAA와 ABP 설정 관련된 부분을 설명한다.

 

  • For OTAA
"lora.device-eui": "{ YOUR_DEVICE_EUI }",
"lora.application-eui": "{ YOUR_APPLICATION_EUI }",
"lora.application-key": "{ YOUR_APPLICATION_KEY }"​
  • For ABP
"lora.over-the-air-activation": false,

"lora.appskey": "{ YOUR_APPLICATION_SESSION_KEY }",
"lora.nwkskey": "{ YOUR_NETWORK_SESSION_KEY }",
"lora.device-address": " YOUR_DEVICE_ADDRESS_IN_HEX  "

ABP를 사용하기 위해선 OTAA를 꺼야 한다. 

 

 

728x90
반응형
반응형

안녕하세요.

 

오늘은 딥러닝에서 가장 많이 사용되는 ReLU를 통해 비선형함수와 선형함수의 차이점을 알아보겠습니다.

 

ReLU 함수

머신러닝에서 선형함수를 통해 회귀문제를 해결할 수 있게 되었고, 더 복잡한 문제를 풀기 위해 비선형 함수 Sigmoid, Tanh, ReLU를 나오기 시작합니다. 

 

현재까지 복잡한 문제를 딥러닝 분야에서 ReLU를 사용하는 것은 당연시 되고 있습니다. 

 

바로, 본론으로 들어가겠습니다.

 

TesorFlow, Keras, Pytorch를 통해 ReLU를 사용하는 것은 굉장히 간단합니다. 

 

신호 및 시스템의 개념적 이야기로 가보겠습니다.

 

ReLU는 왜 비선형 함수일까요?

 

 

 

선형 시스템비선형 시스템의 차이

 

선형성을 가지고 있으면 선형 시스템이고, 그 외는 비선형 시스템입니다.

 

선형성을 가지는 조건은 무엇일까요?

 

세 가지의 조건을 충족하면 선형성을 가진다고 이야기할 수 있습니다. 그 외에는 비선형 시스템으로 분류할 수 있습니다.

 

 

 

 

1. 선형적인 그래프

x = 0 에서 꺽이는 구간을 제외하고 전 구간이 선형성을 가지지만, (x =0) 부분 때문에 선형성을 가진다고 할 수 없습니다. 

 

부끄럽지만, 저는 꺾이는 부분을 제외한 전 구간이 부분 선형형태를 띄우니 선형 함수가 맞지 않나라는 생각을 해 공부를 해서 찾아보았습니다.

 

2. 동차성 ( f(ax) = a * f(x) )

 

ReLU를 간단히 설명하면, x가 0보다 작으면 f(x) = 0, x가 0보다 크면 f(x) = x 입니다. 이를 f(x) = max(0, x)라 표현하겠습니다.

 

 

① a = 3으로 가정하면, 

 

f(3x) = 3x

3 * f(x) = 3x

 

f(3x) = 3 * f(x)  = 3x

 

② a = -3 으로 가정하면

 

f(-3x) = -3x

-3 * f(x) = -3x

 

f(-3x) = -3 * f(x)  = -3x

 

ReLU는 동차성이 성립함을 알 수 있습니다.

 

 

 

 

3. 가산성 ( f(x1 + x2) = f(x1) + f(x2) )

 

x1 = -1, x2 = 2 라고 가정하면,

 

f(-1+2) = 1

 

f(-1) = 0,

f(2) =2 

f(-1) + f(2) = 2

 

f(-1+2) != f(-1) + f(2)

 

ReLU는 가산성이 성립하지 않음을 알 수 있습니다.

 

ReLU는 동차성은 성립하지만, 가산성이 성립하지 않아 선형성을 가지지 않으므로 비선형 함수임을 알 수 있었습니다. 

728x90
반응형
반응형

 

 

 

https://openaccess.thecvf.com/content_cvpr_2017/papers/Chollet_Xception_Deep_Learning_CVPR_2017_paper.pdf

 

안녕하세요.

 

Xception 논문 리뷰 2회차입니다. 

 

1회차 논문리뷰로 An Extreme version of Inception module이 Depthwise Separable Convolution까지 소개했습니다.

 

아래 전 편의 글을 읽는 것을 추천드립니다.

 

https://coding-yoon.tistory.com/78?category=825914

 

[딥러닝 논문 리뷰] Xception: Deep Learning with Depthwise Separable Convolutions (feat.Pytorch)(1)

안녕하세요. 저번 Depthwise Separable Convolution 기법에 대해 글을 올렸습니다. 오늘은 이 기법을 사용한 Xception 논문에 대해 리뷰하도록 하겠습니다. https://openaccess.thecvf.com/content_cvpr_2017/html..

coding-yoon.tistory.com

 

An Extreme version of Inception module과 Depthwise Separable Convolution는 굉장히 비슷한 형태를 가지고 있습니다.

 

논문에서 소개하는 두 개의 차이점을 설명하고 있습니다.

 

Two minor differences between and “extreme” version of an Inception module and a depthwise separable 
convolution would be:

“extreme” version of an Inception module과 depthwise separable 
convolution의 두 가지 사소한 차이점은 다음과 같습니다.

 

 

 

1. Order(순서)

• The order of the operations: 
depthwise separable convolutions as usually implemented (e.g. in TensorFlow)perform first channel-wise 
spatial convolution and then perform 1x1 convolution, whereas Inception performs
the 1x1 convolution first.

Depthwise Separable Convolution : Depthwise Convolution(3x3, 5x5 ...), Pointwise Convolution 

An Extreme version of Inception module : Pointwise Convolution , Depthwise Convolution(3x3, 5x5 ...)

 

Convolution의 순서가 다르다고 합니다.

We argue that the first difference is unimportant, in particular because these operations are meant
to be used in a stacked setting.

 

스택 설정에서 사용되기 때문에 순서의 차이점은 중요하지 않다고 합니다.

 

 

 

2. Non-Linearity(비선형성)

• The presence or absence of a non-linearity after the first operation.
In Inception, both operations are followed by a ReLU non-linearity, however depthwise separable 
convolutions are usually implemented without non-linearities.

ReLU(비선형)의 유무.

 

Inception은 Convolution 수행이 후 ReLU가 붙는 반면, 

 

일반적으로 Depthwise Separable Convolution는 ReLU가 없이 구현됩니다. 

 

The second difference might matter, and we investigate it in the experimental section 
(in particular see figure 10).

 

ReLU의 유무는 중요하며, Figure 10에서 실험 결과를 보여줍니다.

 

Depthwise Separable Convolution에서 ReLU를 사용하지 않았을 때 더 높은 Accruacy를 보여줍니다.

 

It may be that the depth of the intermediate feature spaces on which spatial convolutions are applied 
is critical to the usefulness of the non-linearity:

 for deep feature spaces (e.g. those found in Inception modules) the non-linearity is helpful, 
 but for shallow ones (e.g. the 1-channel deep feature spaces of depthwise separable convolutions) it becomes harmful, 
 possibly due to a loss of information.

 

깊은 특징 공간의 경우, ReLU가 도움이 되지만  얕은 공간( 1x1 Convolution )에서는 ReLU에 의해 정보 손실이 생길 수 있기 때문에 사용하지 않는 것이 좋다는 결과입니다.

 

다음 글은 Xception의 Architecture에 대해 설명하고, Pytorch로 구현함으로 글을 Xception 논문 리뷰를 마치도록 하겠습니다. 피드백주시면 감사하겠습니다.

728x90
반응형

+ Recent posts