Android 입문자를 위한 Tutorial - 6. 커스텀 위젯

Mobile Programming/Android 2010. 11. 9. 14:46

위젯을 사용자가 정의하고 이를 사용한다.

package geng.mm.jnu;

import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.AttributeSet;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.TextView;



public class ch9 extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
    }
}

class Editlength extends LinearLayout implements TextWatcher{
	
	EditText mEdit;
	TextView mText;
	
	public Editlength(Context context) {
  	  
		super(context);
		init();
	}
	public Editlength(Context context,AttributeSet attrs) {
	  	  
		super(context,attrs);
		init();
	}
			
	void init() {
  	
		setOrientation(LinearLayout.VERTICAL);
		mEdit = new EditText(getContext());
		mText = new TextView(getContext());
		mText.setText("Now Length : 0 Char");
		
		LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
				LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT);
		
		addView(mEdit,params);
		addView(mText,params);
		mEdit.addTextChangedListener(this);
	}
	
	@Override
	public void afterTextChanged(Editable arg0) {
		// TODO Auto-generated method stub
		
	}
	@Override
	public void beforeTextChanged(CharSequence s, int start, int count,
			int after) {
		// TODO Auto-generated method stub
		
	}
	@Override
	public void onTextChanged(CharSequence s, int start, int before, int count) {
		// TODO Auto-generated method stub
		mText.setText("Now Length : " + s.length() + "Characters");
	}
}

class EditEcho extends LinearLayout implements TextWatcher{

	EditText mEdit;
	TextView mText;
	
	public EditEcho(Context context) {
		super(context);
		// TODO Auto-generated constructor stub
		init();
	}
	
	public EditEcho(Context context,AttributeSet attrs) {
	  	  
		super(context,attrs);
		init();
	}

	void init() {
	  	
		setOrientation(LinearLayout.VERTICAL);
		mEdit = new EditText(getContext());
		mText = new TextView(getContext());
		mText.setText("Now Length : 0 Char");
		
		LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
				LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT);
		
		addView(mEdit,params);
		addView(mText,params);
		mEdit.addTextChangedListener(this);
	}

	@Override
	public void afterTextChanged(Editable s) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void beforeTextChanged(CharSequence s, int start, int count,
			int after) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void onTextChanged(CharSequence s, int start, int before, int count) {
		// TODO Auto-generated method stub
		mText.setText("Now Length : " + s + "Characters");
	}
	
}

 

외부 클래스로 만들고자 하는 위젯을 만들어야 한다.
본 예제에서의 위젯은 리니어 레이아웃을 기반으로한 텍스트뷰 위젯이므로 먼저 linearlayout을 상속하고, 위젯이 사용해야하는 두 생성자를 사용, 그리고 초기화 함수를 호출하여 위젯을 구성한다.
 두 리니어 레이아웃 모두 텍스트 에디트 + 텍스트뷰이기 때문에 init함수에서 에디트와 텍스트뷰를 add하고 있다.
Text뷰의 변화 감지를위해 addTextChangedLister를 호출하고,
역시 implements 되어있기 때문에 현재 클래스에서 찾을 수 있도록 (this)를 넘겨주었다.
 

Neuron Network - Supervised

Theory 2010. 11. 4. 22:02


신경망에 대해서 수업을 들었지만 사실 이해가 잘 가지 않는다. 
되는대로;; 간략히 정리하자면

사람의 뇌가 Synapse 끼리의 의사소통으로 정보를 전달하는 것은 모두 알고 있을 것이다.


하나의 시냅스에 여러 입력이 들어오고, 그에 따라 단복수의 아웃풋이 있을 것인데,
사람의 이런 인지 메커니즘을 따와서 모델링 한 것이 신경망이다. Perceive + Neuron 으로 Perceptron 이라고도 한다.

다음과 같은 이미지가 될 것이다 .


X1, X2, X3는 인풋이고, F는 시냅스에서 할 내부적인 작업, 그리고 O는 아웃풋이다.
이 아웃풋이 다른 F의 X1, X2, X3가 될 것이다.

그런데 X1, X2, X3는 이대로 들어올 수도 있지만, 시냅스마다 인풋마다 다른 가중치를 적용 할 수도 있다. 그렇게 되면 이미지는

와 같은 형태가 된다.

F의 입장에서, 자신이 가지고 있는 정보는

X_vector = [ x1 x2 x3 ] , W_vector = [ w1 w2 w3 ] 이며,
w1x1 + w2x2 + w3x3 = 0 과 같은 직선의 식을 형성하게 된다. (각 시냅스 별로)

여기서 직선의 식을 형성한다는 말은, Classify에서 각 Class 간을 구분짓는 직선을 만드는 것이 이 초창기 신경망의 주 목적이라는 점을 생각하면 된다.
숫자 인식이라면, 0, 1, 2 ,...9 의 10가지 class가 있는데, 0 그룹들은 2차원(사실 feature에 따라 2차원보다 훨씬많지만) 평면에 맵핑시켰을때 왼쪽 구석에 몰려있었고, 9는 오른쪽 하단 구석에 몰려있었다면, 그 중앙에 직선을 그어주면 된다.
신경망은 직선을 어디에 그을지 학습을 하는 녀석이고,
테스트시에 받은 입력을 갖다가 feature 그래프에 맵핑시켜보니 왼쪽구석에 있었다면 0이라고 출력해주는 형태이다.

예컨데, feature 1과 feature 2 를 특징으로 가지고있고, 이에 따라 확연히 구분되는 O와 X를 고려해보자.


이 둘을 나누기 위한 직선은 무수히 많지만, 그 중 하나를 고를 수 있다.

이 예제는 대단히 classify 하기 쉽지만, 실제 데이터는 이렇게 정갈하지 못한 것이 일반적이다.


위와 같은 분포에서는 불가피하게 두개 이상의 직선을 그릴 수 밖에 없다. 이와 같은 직선을 Peicewise - linear라고 한다.
그러나 위와 같은 linear도 대단히 좋은 경우다.
사실 feature에 따라 엄청나게 복잡한 곡선을 그려야 하며, 인공지능 연구자들은 보다 효율적인 방안을 강구해 내야 했다.

1985 . PDP의 등장

사실 사람이 어떤 정보를 저장할때 3이라는 숫자를 기억한다고하면 "3" 전체를 하나의 세포에 우겨 넣는 것이 아니라,
3을 몇개로 쪼개서 세포 하나하나에 저장한다.

글자 3에서 끝부분이 마저 적어져 있지 않아도 "이건 3이구나!"라고 알아낼 수 있는것도,
어떤 친구가 모자를 안쓰다가 쓰고왔다고 해서 못알아보는 일은 없는것도 이런 PDP(Parallely Distributed Processing)의 속성때문이다.

Neuron Network는 PDP를 충분히 활용한 사례다.
Layer의 노드들이 각각 어떤 정보의 일부분을 저장하고 있으며, 복잡하게 얽혀서 (Massively Connected)그 정보를 저장하고 있다.

Neuron Network의 구조는 다음과 같다.


위와같은 네트워크에서 식은 x1*w11 *a(output레이어로의 간선) + x1*w12*b + x2*w21*a  + x2*w22*b = o 와 같은 형태가 된다.
히든레이어수와 노드가 많아질 수록 식은 훨씬 복잡해지고, 다양한 직곡선을 그릴 수 있게 된다.

학습시키는 방법은 ,

먼저 w들의 값을 초기값으로 아무렇게나 주고, 입력과 아웃풋의 결과를보고 그 MSE( min sqaure error )를 확인,
만약 MSE가 크다면 w들의 값을 조금씩 수정해가는 형태다.
먼저 O의 결과를 보고 A와 B의 간선으로(최종히든레이어 두개) 에러값 만큼 수정 요구를 하면 ,
그 히든레이어는 역시 에러값을 앞으로 전파(propagation)하여 학습을 한다.

'Theory' 카테고리의 다른 글

TCP/IP State Diagram  (0) 2015.02.09

Android 입문자를 위한 Tutorial - 5. ArrayList

Mobile Programming/Android 2010. 11. 4. 14:14

arrayList를 확장하여 이용하는 뷰가 참 많이 있다.

먼저 가장 많이 사용하는 "리스트뷰", 말 그대로 여러정보를 리스트를 뿌려주듯이 뿌려줄 수 있다.

adapter를 이용하기 위해서 먼저 ArrayList를 만들고 ,

ArrayList Items;
ArrayAdapter Adapter;
ListView list;

	Items = new ArrayList();
	Items.add("First");
	Items.add("Second");
	Items.add("Third");



Array Adapter를 만들어줘야한다.
Adapter = new ArrayAdapter(this, android.R.layout.
				simple_list_item_multiple_choice, Items);

그 뒤에 listview에 연결시켜주면 된다.
list.setAdapter(Adapter);
list.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
.


다음으로 스피너는
팝업창을 통해서 리스트 뷰를 띄워주는 형태라고 생각하면 될 것 같다.

다음은 스피너를 이용하는 소스이다.
package geng.mm.jnu;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.RatingBar;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.AdapterView.OnItemSelectedListener;

public class fruitrating extends Activity {
    /** Called when the activity is first created. */
		ArrayAdapter adspin;
		RatingBar mRating;
		TextView mRateText;
		String fruit;
		float rate;
		//채워넣을 곳//
		public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.fruitrating);

		mRating = (RatingBar)findViewById(R.id.ratingbar);
		mRateText = (TextView)findViewById(R.id.ratetext);

		Spinner spin = (Spinner)findViewById(R.id.myspinner);
		spin.setPrompt("과일을 고르세요.");

		adspin = ArrayAdapter.createFromResource(this, R.array.fruits, 
		android.R.layout.simple_spinner_item);
		adspin.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
		spin.setAdapter(adspin);

		spin.setOnItemSelectedListener(new OnItemSelectedListener() {
			public void onItemSelected(AdapterView parent, View view, int position, long id) {
				//채워넣을 곳//
				fruit = (String) adspin.getItem(position);
			}
			public void onNothingSelected(AdapterView parent) {
			}
		});

		mRating.setOnRatingBarChangeListener(new RatingBar.OnRatingBarChangeListener() {
			public void onRatingChanged(RatingBar ratingBar, float rating, boolean fromUser) {
				mRateText.setText("Now Rate : " + rating);
				rate = rating;
				//채워넣을 곳//
				String tmp ;
				if(rate<1){
					tmp = "나빠";
				}else if(rate < 2.5)
					tmp = "괜찮아";
				else if(rate<3.9)
					tmp = "좋아!";
				else 
					tmp = "완전좋아~!!";
				Toast.makeText(fruitrating.this, fruit + "는 "+  tmp , Toast.LENGTH_SHORT).show();

			}
		});
	}
}
;

<string-array name="fruits">
<item>사과</item>
<item>감</item>
</string-array>
와 같이 xml에 넣어주었다.

rating chanaged 메서드와 , itemselected 메서드로 변화를 감지해서 클릭된 스피너의 아이템을 알아내고 그에 따라 토스트를 출력한다.